Malloc 之后的 Strcpy 段错误
Strcpy segfaults after Malloc
所以,我用 C 编写了一个简单的切片函数,它接受一个字符串数组、标记切片开始的字符串和切片的大小。在函数中,我 malloc 一个新数组,然后继续将切片中的每个字符串复制到新数组。但是,我在第一个 strcpy 上遇到了段错误,即使我已经为结果数组分配了 space。
代码如下所示:
char** slice(char** args, char* start, int size){
int i = 0;
// need to find start first
char* cursor = args[0];
int j = 0;
while(cursor != NULL){
if(strcmp(cursor, start) == 0){
break;
}
j++;
cursor = args[j];
}
char** result = malloc(MAX_INPUT * size);
while(i < size){
strcpy(result[i], args[j+i]);
i++;
}
return result;
}
导致段错误的行是--
strcpy(result[i], args[j+i]);
我已经使用 gdb 查看结果和参数中的值,
result[i] 是 0x0,它是 NULL,但 result 本身是一个地址,但我不确定为什么 malloc 不工作。我 运行 出栈了吗 space?这是否意味着我被搞砸了?
result[i]
是未初始化的指针。您犯了与以下相同的错误:
char *ptr;
strcpy(ptr, args[j+i]);
你必须先让 result[i]
指向一些已分配的 space,然后才能将字符复制到其中。此外,MAX_INPUT * size
是分配给指针数组的错误数量 space。
另一个问题是,如果 size
大于 start
之后数组中剩余的字符串数,那么您将读取数组的末尾。
那么你的函数永远不会在新数组的末尾放置一个 NULL
,所以调用者无法知道你返回的切片有多大。
而且cursor
是多余的,你可以直接写成args[j]
。基本上这个功能是一团糟。
代码可能是(警告:未经测试):
char** slice(char** args, char const *start, int slice_size)
{
// Find index of "start"
int start_index;
for (start_index = 0; args[start_index]; ++start_index)
if ( !strcmp(args[start_index], start) )
break;
// Abort if "start" was not present (remove this line if you want to
// instead return an empty terminated list)
if ( !args[start_index] )
return NULL;
// Allocate array of pointers to new strings, allowing space for terminator
char **result = malloc((slice_size + 1) * sizeof *result);
if ( !result )
return NULL;
// Copy strings in, allocating space for each string, stopping if no more args
int i;
for (i = 0; i < slice_size && args[start_index + i]; ++i)
result[i] = strdup(args[start_index + i]);
// Terminate the list
result[i] = NULL;
return result;
}
这一行:
char** result = malloc(MAX_INPUT * size);
mallocs MAX_INPUT 个字符乘以大小。 'size'.
的内容是什么意思
总的来说,需要的是一些我在代码中没有看到的 char *
的 malloc。
然后,在正确获取 malloc 参数后,
代码需要使用 strdup()
而不是 strcpy()
- 或者 - 每个字符串的 malloc 空间然后使用 strcpy()
,可能在包含两个函数调用的循环中
所以,我用 C 编写了一个简单的切片函数,它接受一个字符串数组、标记切片开始的字符串和切片的大小。在函数中,我 malloc 一个新数组,然后继续将切片中的每个字符串复制到新数组。但是,我在第一个 strcpy 上遇到了段错误,即使我已经为结果数组分配了 space。
代码如下所示:
char** slice(char** args, char* start, int size){
int i = 0;
// need to find start first
char* cursor = args[0];
int j = 0;
while(cursor != NULL){
if(strcmp(cursor, start) == 0){
break;
}
j++;
cursor = args[j];
}
char** result = malloc(MAX_INPUT * size);
while(i < size){
strcpy(result[i], args[j+i]);
i++;
}
return result;
}
导致段错误的行是--
strcpy(result[i], args[j+i]);
我已经使用 gdb 查看结果和参数中的值, result[i] 是 0x0,它是 NULL,但 result 本身是一个地址,但我不确定为什么 malloc 不工作。我 运行 出栈了吗 space?这是否意味着我被搞砸了?
result[i]
是未初始化的指针。您犯了与以下相同的错误:
char *ptr;
strcpy(ptr, args[j+i]);
你必须先让 result[i]
指向一些已分配的 space,然后才能将字符复制到其中。此外,MAX_INPUT * size
是分配给指针数组的错误数量 space。
另一个问题是,如果 size
大于 start
之后数组中剩余的字符串数,那么您将读取数组的末尾。
那么你的函数永远不会在新数组的末尾放置一个 NULL
,所以调用者无法知道你返回的切片有多大。
而且cursor
是多余的,你可以直接写成args[j]
。基本上这个功能是一团糟。
代码可能是(警告:未经测试):
char** slice(char** args, char const *start, int slice_size)
{
// Find index of "start"
int start_index;
for (start_index = 0; args[start_index]; ++start_index)
if ( !strcmp(args[start_index], start) )
break;
// Abort if "start" was not present (remove this line if you want to
// instead return an empty terminated list)
if ( !args[start_index] )
return NULL;
// Allocate array of pointers to new strings, allowing space for terminator
char **result = malloc((slice_size + 1) * sizeof *result);
if ( !result )
return NULL;
// Copy strings in, allocating space for each string, stopping if no more args
int i;
for (i = 0; i < slice_size && args[start_index + i]; ++i)
result[i] = strdup(args[start_index + i]);
// Terminate the list
result[i] = NULL;
return result;
}
这一行:
char** result = malloc(MAX_INPUT * size);
mallocs MAX_INPUT 个字符乘以大小。 'size'.
的内容是什么意思总的来说,需要的是一些我在代码中没有看到的 char *
的 malloc。
然后,在正确获取 malloc 参数后,
代码需要使用 strdup()
而不是 strcpy()
- 或者 - 每个字符串的 malloc 空间然后使用 strcpy()
,可能在包含两个函数调用的循环中