C中的指针:分配内存与赋值VS分配内存而不赋值
Posted
技术标签:
【中文标题】C中的指针:分配内存与赋值VS分配内存而不赋值【英文标题】:Pointers in C: Allocating memory with value assignment VS allocating memory without value assignment 【发布时间】:2019-09-11 21:48:54 【问题描述】:只有当我没有为指针分配一些值时,才通过 calloc 分配 Char 指针的内存。
我正在尝试一些简单的示例来更好地理解指针/双指针/三指针/ ...。在编写双指针代码时,我偶然发现了一个非常奇怪的行为。
#define PRINT(X, ...) printf("Address of " X "\n", ##__VA_ARGS__);
...
...
int i = 0;
char buf[12];
char **two_star;
two_star = calloc(10, sizeof(char*));
for (i = 0; i < 10 ; ++i)
two_star[i] = calloc(10, sizeof(char));
PRINT("two_star[%d] = %p", i, two_star[i]);
for (i = 0; i < 10 ; ++i)
two_star[i] = calloc(10, sizeof(char));
snprintf(buf, 12, "pre_%d_suff", i);
two_star[i] = buf;
PRINT("two_star[%d] = %p two_star[%d] = %s", i, two_star[i], i, two_star[i]);
对于上述两个 for 循环,我得到以下结果:
对于循环 1:
Address of two_star[0] = 0xbcc090
Address of two_star[1] = 0xbcc0b0
Address of two_star[2] = 0xbcc0d0
Address of two_star[3] = 0xbcc0f0
Address of two_star[4] = 0xbcc110
Address of two_star[5] = 0xbcc130
Address of two_star[6] = 0xbcc150
Address of two_star[7] = 0xbcc170
Address of two_star[8] = 0xbcc190
Address of two_star[9] = 0xbcc1b0
对于循环 2:
Address of two_star[0] = 0x7ffcd2238ab0 two_star[0] = pre_0_suff
Address of two_star[1] = 0x7ffcd2238ab0 two_star[1] = pre_1_suff
Address of two_star[2] = 0x7ffcd2238ab0 two_star[2] = pre_2_suff
Address of two_star[3] = 0x7ffcd2238ab0 two_star[3] = pre_3_suff
Address of two_star[4] = 0x7ffcd2238ab0 two_star[4] = pre_4_suff
Address of two_star[5] = 0x7ffcd2238ab0 two_star[5] = pre_5_suff
Address of two_star[6] = 0x7ffcd2238ab0 two_star[6] = pre_6_suff
Address of two_star[7] = 0x7ffcd2238ab0 two_star[7] = pre_7_suff
Address of two_star[8] = 0x7ffcd2238ab0 two_star[8] = pre_8_suff
Address of two_star[9] = 0x7ffcd2238ab0 two_star[9] = pre_9_suff
这里的问题很明显。在第二个 for 循环中分配的指针都具有相同的地址值。这意味着 two_star[0] 和 two_star[9] 最终是相同的值,因为相同的内存地址最终会被一次又一次地更新。
【问题讨论】:
memcpy
而不是 two_star[i] = buf;
【参考方案1】:
使用strcpy:strcpy(two_star[i], buf);
而不是two_star[i] = buf;
,因为在您的情况下,您不会复制字符串,只需将指针two_star[i]
重新分配给buf
(这也是内存泄漏,因为您已经丢失了指向已分配内存的指针)。
【讨论】:
这行得通。时间允许时会接受它作为正确答案。【参考方案2】:使用strcpy(two_star[i], buf);
是不够的。
char buf[12];
two_star[i] = calloc(10, sizeof(char));
// snprintf(buf, 12, "pre_%d_suff", i);
strcpy(two_star[i], buf); // bad, trying to put 12 characters into 10
two_star[i] = buf;
目的地太小了。
相反,代码可以调整大小。
int size_needed = snprintf(NULL, 0, "pre_%d_suff", i) + 1;
two_star[i] = malloc(size_needed);
snprintf(two_star[i], size_needed, "pre_%d_suff", i);
注意:为简洁起见,省略了错误检查。
【讨论】:
以上是关于C中的指针:分配内存与赋值VS分配内存而不赋值的主要内容,如果未能解决你的问题,请参考以下文章