C 字符串数组:删除原始数组,然后返回副本
我是C语言的新手,我正在努力理解分配字符串 我正在尝试创建一个名为“添加字符串”的函数。它接受一个包含零个或多个字符串的数组,该数组的最终位置为null。接下来,它将使数组的浅层副本增大+1个位置,然后将字符串C 字符串数组:删除原始数组,然后返回副本,c,arrays,C,Arrays,我是C语言的新手,我正在努力理解分配字符串 我正在尝试创建一个名为“添加字符串”的函数。它接受一个包含零个或多个字符串的数组,该数组的最终位置为null。接下来,它将使数组的浅层副本增大+1个位置,然后将字符串str的副本附加到数组上。最后,它删除原始数组并返回新的副本 这就是我到目前为止所做的: char **adding_string(char **array, const char *str) { size_t num = strlen(str) + 1; char *f
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;
以下计划严格遵循您的需求和意图 每次添加新字符串时,都会调整数组
数组的大小。在程序结束时,所有分配的内存都会被正确清理
#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;
}
这是一种不同的方法
char *adding_string(const char *str)
返回指向字符串副本的指针(char*)
。数组
已经预先分配了内存以容纳所有字符串指针
演示该概念的小程序:
#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;
}
您的添加\u字符串
没有意义,您复制了str
,释放内存
从数组
返回新副本。该函数应返回一个指向char
的双指针,
您正在向char
传递一个指针。所有其他值都将丢失,您将丢失
疯狂地泄露记忆
我会重写你的添加字符串如下:
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;
}
请注意,在此版本中,如果数组
为NULL
,则函数将为
字符串数组。这只是一个设计选择,你也可以检查一下
array
不是NULL
并传递给adding\u 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
空格,这是
尺寸+2
请不要忘记以后释放内存。您不是在复制数组,而是在复制str。final的类型是char*
,这就是为什么它会显示“不兼容指针类型”-函数应该返回char**
。@rain city,这很有意义,谢谢。如果我错了,请纠正我,但要解决这个问题,我必须将str更改为array,然后使用strncat将两者相加。接下来,我将返回char**,这将是数组。为什么*行会变为null?@QuasselKasper是一种模拟cstring如何通过使用'\0'
-终止字节来终止的技术。这里有一个NULL
指针<main
中的code>argv
就是这样工作的,最后一个元素是NULL
。例如,execv
也要求这样做。非常感谢!这很有道理!
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);