您已经为30个指针分配了空间,但您没有将它们初始化为指向任何有意义的地方。除非您在函数外声明了该数组,否则数组中的每个元素都将包含一些随机的位字符串,这些字符串可能与可写内存位置相对应,也可能不相对应。如果我们画出一张图片,它会像这样(所有地址都是凭空想象的;不要假设这与任何真实的架构相对应):
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
ptr 0xbbc81230 0x?? 0x?? 0x?? 0x??
0xbbc81234 0x?? 0x?? 0x?? 0x??
0xbbc81238 0x?? 0x?? 0x?? 0x??
...
0xbbc812a8 0x?? 0x?? 0x?? 0x??
其中
0x??
表示随机字节值。对于您描述的行为,每个随机值“恰好”指向可写内存,并且覆盖存储在那里的任何内容“恰好”不会产生任何立即的不良影响。
坏结果:当您的代码表现良好时,实际上它的行为非常糟糕,并且可能会导致程序中其他地方的一些令人讨厌的运行时问题,这很难调试。
在尝试通过它写入之前,您需要显式设置
ptr
数组的每个元素以指向有效的内存位置。
假设我们添加以下代码:
ptr[0] = malloc(strlen("foo") + 1);
strcpy(ptr[0], "foo");
ptr[1] = malloc(strlen("bar") + 1);
strcpy(ptr[1], "bar");
我们动态分配了一些额外的内存来容纳一些字符串,并将这些新缓冲区的指针存储到
ptr[0]
和
ptr[1]
中。
我们的图片现在会看起来像这样:
项目 地址 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
0x80ff0000 'f' 'o' 'o' 0x00
...
0x80ffcdc0 'b' 'a' 'r' 0x00
...
ptr 0xbbc81230 0x80 0xff 0x00 0x00
0xbbc81234 0x80 0xff 0xcd 0xc0
0xbbc81238 0x?? 0x?? 0x?? 0x??
...
0xbbc812a8 0x?? 0x?? 0x?? 0x??
ptr[0]
现在包含一个大小为4个
char
值的缓冲区的地址,我们将字符串 "foo" 复制到该缓冲区。同样,
ptr[1]
包含另一个4字节缓冲区的地址,该缓冲区现在包含字符串 "bar"。
scanf
和printf
之间做一些事情。你应该会看到一些未定义的行为。 - stanwise