gpt4 book ai didi

c - 在将 strlcpy 与 char ** 类型一起使用后,值有时会被覆盖

转载 作者:太空宇宙 更新时间:2023-11-04 06:57:21 25 4
gpt4 key购买 nike

我最近一直在努力学习 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) 来正确地做到这一点。但是,根据错误的位置,我仍然有理由相信问题可能出在我释放内存的方式上。我只是不知道我做错了什么。

如有任何建议,我们将不胜感激。谢谢!

最佳答案

问题是这样的:char **strings = malloc(sizeof(**strings) * length);

请注意,您正在分配 sizeof(**strings)char ** 两次解引用只是一个 char,所以 sizeof(**strings) 是 1。所以你只分配了 3 个字节。这不是你想要的。

相反,您需要 sizeof(*strings),它存储在 strings 中。这将是一个 char * 并且将是 4 或 8,具体取决于您是 32 位还是 64 位。

关于c - 在将 strlcpy 与 char ** 类型一起使用后,值有时会被覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42634203/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com