C 用最后一个元素覆盖的数组成员

C 用最后一个元素覆盖的数组成员,c,C,通过下面的代码,我得到了一个非常复杂的结果。为什么最后一个元素的值会覆盖所有以前的数组元素?我怀疑有一个比这个中间问题更大的问题 #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

通过下面的代码,我得到了一个非常复杂的结果。为什么最后一个元素的值会覆盖所有以前的数组元素?我怀疑有一个比这个中间问题更大的问题

#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
#包括
main()
{
int i,案例;
字符数[1000000];
scanf(“%d”和案例);
字符*数组[案例];
//在数组中存储输入

对于第一个循环中的(i=0;i),您应该(但不是)将每个输入写入num数组的不同元素;相反,您总是写入同一个位置,即写入第一个循环中的
&num

,您应该(但不是)将每个输入写入num数组的不同元素;相反,您总是写入同一个位置,即写入
&num
这里的结果是行
数组[i]=&num;
您正在设置
数组[i]的值
元素到
num
数组的地址;由于
array
是一个字符数组,我怀疑它截断了
num
数组地址,低阶字节恰好是3


然而,也就是说,您的char num[1000000]是一种可怕的形式,您根本不应该这样做。在堆上分配,并选择一个较小的数字,看在上帝的份上。此外,scanf(“%s”,&num)实际上不会给您想要的。这里有一个提示;使用getc()循环读取数字;这避免了对scanf()进行任何数组预分配。

这里的结果是
数组[i]=&num;
您正在设置
数组[i]的值
元素到
num
数组的地址;由于
array
是一个字符数组,我怀疑它截断了
num
数组地址,低阶字节恰好是3

然而,也就是说,您的char num[1000000]是一种可怕的形式,您根本不应该这样做。在堆上分配,并选择一个较小的数字,看在上帝的份上。此外,scanf(“%s”,&num)实际上不会给您想要的。这里有一个提示;使用getc()循环读取数字;这避免了为scanf()预分配数组。

char*array[cases]

这是在编译时分配的,而不是在运行时分配的。而且cases没有初始化(尽管我认为您希望它能够动态工作)。因此,您需要预先分配内存,或者熟悉malloc系列库函数。

char*array[cases]


这是在编译时分配的,而不是在运行时分配的。而且案例没有初始化(尽管我认为您希望它能够动态工作。)因此,您需要预先分配内存,或者熟悉malloc库函数系列。

这就是您的代码:

#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;
}
这有点防御性。我不知道你为什么需要100000。你可以使用malloc动态完成。这将涉及更多的工作,但非常健壮


代码中出现的情况是,将字符串%s存储到num的地址,该地址不变,然后将array[i]元素分配给该地址。在C中分配元素只是存储引用,而不存储元素本身-这将浪费空间。因此,由于所有数组元素都指向该地址(只存储引用),地址中的值会发生变化,引用也会发生变化,这就是为什么它们都会变为2(而不是你在帖子中所说的3)。

这就是你的代码:

#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;
}
这有点防御性。我不知道你为什么需要100000。你可以使用malloc动态完成。这将涉及更多的工作,但非常健壮


代码中出现的情况是,将字符串%s存储到num的地址,该地址不变,然后将array[i]元素分配给该地址。在C中分配元素只是存储引用,而不存储元素本身-这将浪费空间。因此,由于所有数组元素都指向该地址(只存储引用),地址中的值会发生变化,引用也会发生变化,这就是为什么它们都会变为2(而不是你在文章中所说的3)。

这是因为你在数组的每个索引中都放了相同的地址(char num[1000000];)的地址)

这是一个会导致您进行动态分配(calloc、malloc、new等)的错误


干杯!

这是因为您在数组的每个索引中都放置了相同的地址(char num[1000000];)的地址)

这是一个会导致您进行动态分配(calloc、malloc、new等)的错误

干杯!

替换

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}
    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 

要实际打印存储在
a[]
中的地址,而不是
a[]
元素的地址,需要强制转换,因为
%p
需要指向
void
的指针,所以必须提供一个。

替换

//store inputs in array
for(i=0; i<cases; i++)
{
    scanf("%s", &num);
    array[i] = &num;
}
    printf("%d %p\n", i, &array[i]); //print (array index) (array address) 


实际打印存储在
a[]
中的地址,而不是
a[]元素的地址因为代码<> %p/COD>期望指针指向“代码>空格”,所以必须强制转换,所以必须提供一个。

< P>这是C++所做的事情。用户输入解析和动态分配是更安全、更轻而易举的。 我想不出一个系统,你有那种用户界面,你不能切换到C++。 当然,如果这只是一个测试摘录,从其他代码遭受的问题,那么当然


对于C初学者来说,您的代码有几个常见的错误,现在不应该这样做

如果我理解正确,您希望保存sereval用户输入字符串(您的示例输出有点误导,因为您只显示数字)

您正在准备数组以保存指向字符串的所有(事例计数)指针,但您只为一个字符串保留内存。您需要为每个字符串都保留内存,所以是事例。为了使事情在“动态me”方面保持简单