c - C中的指针:分配内存与赋值VS分配内存而不赋值
问题描述
仅当我没有为指针分配某些值时,才通过 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] 最终是相同的值,因为相同的内存地址最终会一次又一次地更新。
解决方案
使用strcpy :strcpy(two_star[i], buf);
而不是two_star[i] = buf;
,因为在您的情况下,您不复制字符串,只需重新分配指向的指针two_star[i]
(buf
这也是内存泄漏,因为您丢失了指向已分配内存的指针)。
推荐阅读
- javascript - 如何在 JavaScript 中获取 API?
- android - React Native 应用程序在 android 上被拒绝后台权限请求
- ios - 对同一个远程 URL 使用 URLSessionDataTask 和 URLSessionDownloadTask 时观察进度
- apache-spark - 为什么 SparkSession.sql() 不适用于 SELECT 查询?
- javascript - 在反应中围绕地图制作包装器功能
- visual-studio-code - VS Code:使用 CMake 工具包含外部 OpenCV 安装
- python - 弹性 beantalk 上的 Firebase Admin SDK 问题
- python - 在 Numpy np.where 子句中减去 2 个日期时间值时引发值错误
- ruby-on-rails - 为 Rails 应用程序存储密码的最佳做法是什么?
- r - graphviz中的排序流程图