通过下面的代码段,得到了一个非常奇怪的结果。为什么最后一个元素的值覆盖所有以前的数组元素?我怀疑不仅仅是这个immmediate问题一个更大的问题。

#include <stdio.h>

main()
{
    int i, cases;
    char num[1000000];

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        scanf("%s", &num);
        array[i] = &num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value) 
        printf("%d %p\n", i, &array[i]); //print (array index) (array address) 
    }
}

Inputs:
3 <-- number of lines to follow
0   <-- put in array[0]
1   <-- put in array[1]
2   <-- put in array[2]

Outputs
0 3         <-- why is this being overwritten with the last element?
0 0013BCD0
1 3         <-- why is this being overwritten with the last element?
1 0013BCD4
2 3
2 0013BCD8

没有正确的解决方案

其他提示

这里的结果是array[i] = &num;你设置array[i]元件到num数组的地址的值的线;因为array是字符数组,我怀疑这是您的截断阵列num地址和低位字节恰好是一个3。

然而。这就是说,你的字符NUM [百万]是可怕的形式,你不应该这样做,在所有。在堆上分配,并选择一个较小的数字,看在上帝的份。此外,scanf函数(“%S”,与NUM)实际上不会给你想要的东西。这里有一个提示;使用GETC()循环来读取数;这避免了需要做的阵列的对的scanf)任何预分配(

这是因为要在该数组的每个索引把相同的地址(字符NUM [百万]的地址)。

这是一个错误,这将导致你的动态分配(释放calloc,malloc的,新的,等等)。

干杯!

在第一个循环中,你应该(但不是)写入各输入到NUM阵列的不同元件;而不是你总是写在同一个地方,即到&num

的char *阵列[例];

这是在编译时被分配,而不是运行时间。和案件未初始化(虽然我觉得你想让它动态反正工作。)所以,你要么需要预分配内存,或熟悉的malloc系列的库函数。

替换

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}

array[0] = num;
//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", array[i]);
    array[i+1] = array[i] + strlen(array[i]) + 1;
}

扫描每个字符串转换成在num[]第一可用的空间,并设置array[]的下一个元素,以指向下一个可用的空间。现在你的琴弦printf()会工作。原来,每串扫描到num[]的开始。

注意:scanf()与缦%sgets()那么糟糕,因为它把对将中咕噜咕噜的数据量没有限制不要在实际代码中使用它

替换

    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 

    printf("%d %p\n", i, (void*)(array[i])); //print (array index) (array address) 

实际打印存储在a[]地址,而不是a[]的元素的地址。因为%p期望一个指针tovoid所以必须提供一个铸造是必需的。

那您的代码,其被固定:

#include <stdio.h>

main(void)
{
    int i, cases;

    scanf("%d", &cases);
    char* array[cases];

    //store inputs in array
    for(i=0; i<cases; i++)
    {
        char *num = malloc(100000);
        scanf("%s", num);
        array[i] = num;
    }

    //print out array items and their memory addresses
    for(i=0; i<cases; i++)
    {
        printf("%d %s\n", i, array[i]);  //print (array index) (array value)
        printf("%d %p\n", i, (void*)&array[i]); //print (array index) (array address)
    }
    return 1;
}

可以如用

char *num = calloc(100000, sizeof(char));

这是一点点的防守。我不知道为什么你需要100000你可以使用malloc做到动态。这将涉及更多的工作,但非常稳健。

什么在您的代码hapenning是你存储字符串%s到NUM不改变的地址,然后分配数组[I]元件到该地址。用C分配是没有别的然后存储参考,不元素存储itself-这将是浪费空间。所以,所有的数组元素指向的地址(只存储参考),在ADRESS变化值,从而使做参考,这就是为什么他们都更改为2(不是3,你在您的文章说明)。

这对于这样的事情,C ++似乎制成。用户输入解析和动态分配完成更安全,并且在微风。 我想不出,你就有了那样的用户界面,在这里你不能切换到C ++的系统。

当然,如果这是只从从问题遭受其他代码测试摘录,那么当然...


您的代码从对C初学者和东西几种常见的错误,不应该做现在这样受到影响。

如果我理解正确的话,你要保存sereval用户输入的字符串(例如你的输出是有点误导,因为你只显示号码)。

您正在准备数组来保存所有的(病例数)指向字符串的指针,但你只保留内存为一个字符串。你需要做的,对于每一个字符串,这样的情况下。为了简单起见,在“动态内存分配”的教训来看,我建议这样做的:char* array[cases][10000];这使你的10K字符的字符串的情况下

您可能也不想有单独的指向你的数组元素。这变得有意义,如果你想在这些元素比指针本身大到一个数组中的元素进行排序。在这种情况下,你的性能增益不具有移动(复制)大块,但只有指针(通常为4个字节)。在你的情况下,一个int也是4个字节长。而你不无论如何排序:)

scanf()是危险的,至少可以说。在你的第二个应用程序,你指示它来写一个字符串数组的地址。这似乎是一个简单的错误,但可能会导致很多问题。你可能想这样做的:scanf("%d", &array[i]);(不幸的是,我没有在手的编译器,所以我不是100%确定)。降下一行:)


问题以降价专家:?为何如此该死不可能有列出了与CODE块组合

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top