我有一个函数alloc_str,它使用一个字符串指针和一个指针数组。它动态地将数组的大小增加一,并将字符串追加到数组中。我已经运行了GDB调试器,并在下面突出显示了我的内存泄漏和const错误。
我期望的输入/输出:
array = alloc_str(array, "test_1");
array = alloc_str(array, "test_2");
array = alloc_str(array, "test_3");
--> ["test_1", "test_2", "test_3"]
我的alloc_str函数:
char **alloc_str(char **existing, const char *add)
{
int length = 0; //find the length of the array
for (; existing[length]; length++)
{
}
//allocate memory to copy array array
char **existing_c = (char **)calloc(length + 2, sizeof(char *));
for (int i = 0; i < length; i++) //copy original array into new array
{
existing_c[i] = existing[i];
}
//possible memory leak error
strncat(existing_c, add, sizeof(existing_c) - strlen(existing_c) - 1);
existing_c[sizeof(existing_c)-1] = '\0';
//possible memory leak error
strncpy(existing, existing_c, sizeof(existing - 1));
s_copy[sizeof(destsize)-1] = '\0'; //error here
free(existing);
return existing_c;
}
void free_array(char **strings) //free's data in array, should be fine
{
int length = 0;
for (; strings[length]; length++)
{
}
strings = (char **)calloc(length + 2, sizeof(char *));
}
我的主要功能:
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(){ //should be fine
char **array = NULL;
char **test;
array = (char **)calloc(1, sizeof(char *)); //array has no strings yet
array = alloc_str(array, "test_1");
array = alloc_str(array, "test_2");
array = alloc_str(array, "test_3");
for (test = array; *test; test++)
{
printf("%s\n", *test);
}
free_array(array);
}
我的错误:
Subscript of pointer to function type 'void (const void *, void *, size_t)' (aka 'void (const void *, void *, unsigned long)')
答案 0 :(得分:2)
存在多个问题:
char **alloc_str(char **existing, const char *add)
{
int length = 0; //find the length of the array
for (; existing[length]; length++)
{
}
//allocate memory to copy array array
char **existing_c = (char **)calloc(length + 2, sizeof(char *));
for (int i = 0; i < length; i++) //copy original array into new array
{
existing_c[i] = existing[i];
}
////////////////////////////////////
//possible memory leak error
strncat(existing_c, add, sizeof(existing_c) - strlen(existing_c) - 1);
existing_c[sizeof(existing_c)-1] = '\0';
//possible memory leak error
strncpy(existing, existing_c, sizeof(existing - 1));
s_copy[sizeof(destsize)-1] = '\0'; //error here
////////////////////////////////////
free(existing);
return existing_c;
}
标有////////////////////////////////////
的部分没有多大意义。
您分配了一个指针数组。不要像对待字符串一样对待它。它不是字符串。 相反,只需将新指针分配给数组的末尾并再次添加终止符即可。
existing_c[length] = add;
existing_c[length+1] = NULL;
有了该终结器,您可以使用普通的malloc
而不是calloc
,因为您仍然可以分配数组的所有元素。
除了分配问题之外,还有另一个内存泄漏:
void free_array(char **strings) //free's data in array, should be fine
{
int length = 0;
for (; strings[length]; length++)
{
}
strings = (char **)calloc(length + 2, sizeof(char *));
}
将指针传递给指针数组。该数组占用一些您之前用calloc
分配的内存。
然后,您分配更多的内存,并将地址分配给局部变量string
。
这有两个问题:
最后,您的free_array
函数不会释放任何东西,但会占用更多内存。
存储在该数组中的字符串可能会出现另一个问题。 在您的示例中,您使用字符串文字。这些是静态对象,无需释放它们。
如果您还将使用函数存储指向动态分配的字符串的指针,则还需要注意分配和释放字符串。
答案 1 :(得分:1)
strncat()
在包含NUL
终止(也称为“ C”)字符串的内存缓冲区上工作:
char buf[10] = {'a', 'b', 'c', '\0'};
strncat(buf, "def", sizeof(buf) - strlen(buf) - 1);
assert(strcmp(buf, "abcdef") == 0); // buf now equals to "abcdef"
(好吧,strlen()
的使用有点抵消了strncat()
优于好的strcat()
的好处,但这是另一个故事……)
因此,它与您在运动中想要做的非常不同。您实际上不需要strncat()
或strncpy()
中的任何一个。