我最近一直在努力学习C以更好地理解(相对)低级编程,因为我通常在Python,PHP,Swift,Java,Javascript等工作中完成大部分工作。我想我理解指针的概念以及如何分配/释放内存,但在一个特定的实例中,我很困惑。似乎有时(可能<10%的时间)我必须测试strlcpy
的一些代码会产生意想不到的结果。其他90%以上的时间,按预期工作。以下是我正在运行的代码,其中包含描述我的意图的评论:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void populate(int length, size_t size, char **strings) {
char test[5] = "test"; //the string we use to populate our incoming array
for (int i = 0; i < length; ++i) //iterate through the length of the string array
{
strings[i] = malloc(sizeof(*strings) * size); //allocate memory for this string to the size of {size}
strlcpy(*(strings + i), test, size); //copy our test string to the string at index {i} of our array
printf("%p - ", (void *) strings[i]); //print the address as a dummy check
printf("String %d: %s\n", i, strings[i]); //confirm our string is being copied as expected
}
}
int main() {
int length = 3; //the length of our array of strings
size_t size = 5; //the length of each string
char **strings = malloc(sizeof(**strings) * length); //a pointer to a {length}-element array of char pointers
printf("Start iteration 1\n");
populate(length, size, strings); //a function which fills **strings with {length} strings of size {size}
printf("Start iteration 2\n");
for (int i = 0; i < length; ++i) //iterate through each string to validate the result
{
printf("%p - ", (void *) strings[i]); //print the address as a dummy check
printf("String %d: %s\n", i, strings[i]); //display our string at index {i}
free(strings[i]); //free the memory of this string
}
free(strings); //free the memory of our string array
return 0;
}
我构建这个是为了更好地理解**
指向指针的语法和逻辑。在大多数情况下,一切似乎都运行正常,我将在我的控制台中获得以下打印输出:
Start iteration 1
0x7ffd70c027a0 - String 0: test
0x7ffd70c027b0 - String 1: test
0x7ffd70c027c0 - String 2: test
Start iteration 2
0x7ffd70c027a0 - String 0: test
0x7ffd70c027b0 - String 1: test
0x7ffd70c027c0 - String 2: test
Process finished with exit code 0
但是,有时候,在第二次迭代中显示仅的一些值要么不正确,要么导致我认为是分段错误:
Start iteration 1
0x7f9f78f00840 - String 0: test
0x7f9f78f00850 - String 1: test
0x7f9f78f00860 - String 2: test
Start iteration 2
0x7f9f78f00840 - String 0: �x�
0x7f9f78f00850 - String 1: test
Process finished with exit code 11
我无法弄清楚为什么会发生这种情况,但我认为根据我的结果,我可以安全地假设它超出了populate
函数的范围。我的指针算术有问题吗?在某些情况下,我没有分配足够的内存吗?
最初,我认为这可能与我在main
函数结束时释放内存的方式有关,但我在SO中查找了几个问题,发现我似乎是通过在释放外部数组(*strings
)之前首先释放内部数组(strings
)来正确执行此操作。但是,基于错误的位置,我仍然有理由相信问题可能与我如何释放内存有关。我只是无法弄清楚我做错了什么。
任何建议将不胜感激。谢谢!
答案 0 :(得分:3)
问题是:char **strings = malloc(sizeof(**strings) * length);
请注意,您正在分配sizeof(**strings)
。 char **
解除引用两次仅为char
,因此sizeof(**strings)
为1.因此,您只需分配3个字节。那不是你想要的。
相反,您需要sizeof(*strings)
,该内容存储在strings
中。这将是char *
,将是4或8,具体取决于你是32位还是64位。