我是C的新手,我正在努力理解分配字符串。
我正在尝试创建一个名为adding_string
的函数。它接收零个或多个字符串的数组,在最终位置具有null。接下来,它将数组的浅表副本放大+ 1位置,然后将字符串str
的副本附加到数组上。最后,它删除原始数组并返回新副本
这是我到目前为止所做的:
char **adding_string(char **array, const char *str)
{
size_t num = strlen(str) + 1;
char *final= (char *)malloc(num);
strncpy(final, str, num);
free(array);
//The above code would create a copy of the string "str".
//Then it puts that into the array.
//Not sure if free(array); would be the right method
//Having issues with returning final too
return final;
}
在main
函数中,你会有类似的东西:
char **array = NULL;
char **lines;
array = (char **)calloc(1, sizeof(char *));
array = adding_string(array, "help");
array = adding_string(array, "plz");
array = adding_string(array, "thanks");
for (lines = array; *lines; lines++)
{
printf("%s\n", *lines);
}
我不确定free(array)
是否是用于删除原始数组的正确方法,而且我在返回新副本时遇到问题。
当我尝试返回新副本时,我得到:
warning: return from incompatible pointer type
这是因为:
return final;
答案 0 :(得分:2)
你的adding_string
毫无意义,你复制str
,释放记忆
来自array
并返回新副本。该函数应该返回一个指向char
的双指针,
您正在将单指针传递给char
。所有其他价值观都会丢失,你是
像疯了一样泄露记忆。
我会像这样重写你的adding_string
:
char **adding_string(char **array, const char *str)
{
char **tmp;
if(str == NULL)
return NULL;
// first make copy
size_t len = strlen(str);
char *strcopy = malloc(len+1);
if(strcopy == NULL)
return NULL;
// you've allocated enough memory for the copy
// no need of strncpy here
strcpy(strcopy, str);
// get the number of strings saved
size_t size = 0; // number of strings saved
if(array)
{
tmp = array;
while(*(tmp++))
size++;
}
// reallocate memory for array of strings
tmp = realloc(array, (size+2) * sizeof *tmp);
if(tmp == NULL)
{
// something went wrong, free the copy
free(strcopy);
return NULL;
}
tmp[size] = strcopy;
tmp[size+1] = NULL;
return tmp;
}
请注意,在此版本中,如果array
为NULL
,则函数会为此分配内存
字符串数组。这只是一个设计选择,你也可以检查一下
array
不是NULL
并且传递给adding_string
预先分配的数组
字符串。我认为(这只是我的意见)更优雅
adding_string
将创建第一个数组。就这样,代码那样
分配内存只在一个地方。
现在在你的主要
char **array = NULL;
char **lines;
// adding_string will allocate the memory for array when it's NULL
array = adding_string(array, "help");
array = adding_string(array, "plz");
array = adding_string(array, "thanks");
for (lines = array; *lines; lines++)
{
printf("%s\n", *lines);
}
请注意,我
tmp = realloc(array, (size+2) * sizeof *tmp);
size
保存了字符串数,这意味着array
保留size+1
个空格,因为最后一个指向NULL
。你正在追加
还有一个字符串,所以你必须重新分配size+1+1
个空格
size+2
。
请不要忘记随后释放记忆。
答案 1 :(得分:1)
以下程序严格遵循您的需求和意图。
每次添加新字符串时,都会调整数组array
的大小。在程序结束时,完成所有已分配内存的正确清理。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char ** adding_string(char **array, const char *str)
{
size_t num = strlen(str) + 1;
char *final = (char *)malloc(num); // allocate memory for the string `str`
strncpy(final, str, num); // create the copy of the `str`
int i=0;
for(i=0; array[i] !=NULL; i++) {} // find how many elements do we have in the array
array[i] = final; // add final to the first empty spot in the `array`
i++;
char ** new_array = calloc(1+i, sizeof(char *)); // allocate a new array 1 size bigger
memcpy(new_array, array, sizeof(char*)*i); // copy all the pointers
free (array); // no need for the old array
return new_array; // return a pointer to the new bigger array
}
int main(void)
{
char **array = NULL;
char **lines;
array = (char **)calloc(1, sizeof(char *)); // allocate array for 4 poiters if type (char *)
array = adding_string(array, "help");
array = adding_string(array, "plz");
array = adding_string(array, "thanks");
for (lines = array; *lines; lines++)
{
printf("%s\n", *lines);
free(*lines);
}
free (array);
return 0;
}
输出:
help
plz
thanks
这是不同的方法
char *adding_string(const char *str)
将指针(char *)
返回给字符串的副本。 array
已经预先分配了内存以容纳所有字符串指针。
一个展示这个概念的小程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *adding_string(const char *str)
{
size_t num = strlen(str) + 1;
char *final= (char *)malloc(num); // allocate memory for the string str
strncpy(final, str, num); // crreate the copy
return final; // return a pointer to created copy
}
int main(void)
{
char **array = NULL;
array = (char **)calloc(4, sizeof(char *)); // allocate array for 4 pointers if type (char *)
array[0] = adding_string("help");
array[1] = adding_string("plz");
array[2] = adding_string("thanks");
for (int i=0; i<3; i++ )
{
printf("%s\n", array[i]);
free(array[i]);
}
free (array);
return 0;
}
输出:
help
plz
thanks