[英]Reallocing an array of strings
So I made this function that receives an unknown amount of strings and adds them into an array of strings. 因此,我制作了此函数以接收未知数量的字符串,并将其添加到字符串数组中。
char **receiveCode(int socket){
int line = 0;
size_t lines = 1;
size_t size = 1;
char** code = malloc(sizeof(char)*size);
while(1){
package_struct *aPackage = receivePackage(socket);
if(aPackage->type=='F'){break;}
size = size + aPackage->size;
code = realloc(code, size);
code[line] = malloc(sizeof(char)*aPackage->size);
strcpy(code[line],aPackage->package);
line++;
lines++;
free(aPackage);
}
code = realloc(code, size + 2);
code[line] = malloc(sizeof(char)*3);
code[lines]=NULL;
return code;
}
Sometimes when I run this code I get the following error 有时,当我运行此代码时,出现以下错误
* glibc detected *检测到glibc ./pp: realloc(): invalid next size: 0x00007f0f88001220 * * ./pp:realloc():下一个无效大小:0x00007f0f88001220 * *
Which, according to Valgrind, happens in that function. 根据Valgrind所说,这发生在该函数中。
Probably I am using too many mallocs and reallocs... not sure though. 可能我使用了太多的malloc和reallocs ...虽然不确定。
I think the problem is this : 我认为问题是这样的:
char** code = malloc(sizeof(char)*size);
It should be char *
instead of char
inside sizeof()
它应该是char *
而不是sizeof()
的char
char** code = malloc(sizeof(char*)*size);
Since code
is a pointer to string so allocate memory for pointers that is char*
由于code
是指向字符串的指针,因此请为char*
指针分配内存
Also there is same kind of problem in realloc
在realloc
也有同样的问题
I assume this is to allocate an array of char*
: 我假设这是分配一个char*
数组:
code = realloc(code, size);
Should be 应该
code = realloc(code, size * sizeof(char*));
// and this one too
code = realloc(code, size + 2 * sizeof(char*));
Also, you don't need this: 另外,您不需要:
char** code = malloc(sizeof(char)*size);
If you call realloc(NULL, size)
it's equivalent to malloc(size)
如果调用realloc(NULL, size)
则相当于malloc(size)
size_t size = 0;
char** code = NULL;
...
code = realloc(code, size * sizeof(char*));
Note: lines
seems useless to me, in fact in the last two lines you overwrite the memory you just allocated since line==lines
注意: lines
对我来说似乎没用,实际上,在最后两行中,您覆盖了刚刚分配的内存,因为line==lines
Here's a version that uses strdup()
to simplify allocation of memory for each new line of text. 这是一个使用strdup()
简化每个新文本行的内存分配的版本。 It also uses 'x' versions of memory allocation functions to simplify out-of-memory error handling (a somewhat common idiom, even if non-standard). 它还使用“ x”版本的内存分配函数来简化内存不足错误处理(即使是非标准的,也是一种常见的习惯用法)。
So all the complexity that really remains (which ends up being not too much) is in managing the growth of the array of string pointers. 因此,真正剩下的所有复杂性(最终不会太多)都在于管理字符串指针数组的增长。 I think this makes it easier to separate handling each string from handling the array of pointers. 我认为这样可以更轻松地将处理每个字符串与处理指针数组分开。 The original code got these two areas confused. 原始代码混淆了这两个方面。
// these variants allocate memory, but abort program on failure
// for simplified error handling - you may need different
// error handling, but often this is enough
//
// Also, your platform may or may not already have these functions
// simplified versions are in the example.
void* xmalloc( size_t size);
void* xrealloc(void* ptr, size_t size);
char* xstrdup(char const* s);
char** receiveCode(int socket){
size_t lines = 0;
char** code = xmalloc( (lines + 1) * sizeof(*code));
*code = NULL;
while(1){
package_struct *aPackage = receivePackage(socket);
if(aPackage->type=='F') {
free(aPackage); // not 100% sure if this should happen here or not.
// Is a `package_struct` with type 'F' dynamically
// allocated or is a pointer to a static sentinel
// returned in this case?
break;
}
// why use `aPackage->size` when you use `strcpy()` to
// copy the string anyway? Just let `strdup()` handle the details
//
// If the string in the `pckage_struct` isn't really null terminated,
// then use `xstrndup(aPackage->package, aPackage->size);` or something
// similar.
char* line = xstrdup(aPackage->package);
++lines;
// add another pointer to the `code` array
code = xrealloc(code, (lines + 1) * sizeof(*code));
code[lines-1] = line;
code[lines] = NULL;
free(aPackage);
}
return code;
}
void* xmalloc(size_t size)
{
void* tmp = malloc(size);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
void* xrealloc(void *ptr, size_t size)
{
void* tmp = realloc(ptr, size);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
char* xstrdup(char const* s)
{
char* tmp = strdup(s);
if (!tmp) {
fprintf(stderr, "%s\n", "failed to allocate memory.\n";
exit(EXIT_FAILURE);
}
return tmp;
}
Also, I think it should be clarified if aPackage->package
is a string pointer or if it's the actual location of the char[]
holding the string data (ie., should &aPackage->package
be passed to strcpy()
/ xstrdup()
?). 另外,我认为应该澄清aPackage->package
是一个字符串指针还是它是保存字符串数据的char[]
的实际位置(即,应将&aPackage->package
传递给strcpy()
/ xstrdup()
?)。 If it really is a pointer, should it be freed before aPackage
is? 如果确实是指针,是否应该在aPackage
之前将其释放?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.