我正在编写一个程序,它接受一个路径列表(环境变量),分割路径并打印出来。在编译它时,我得到一个segfault以下是我在GDB上的输出:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400eb0 in dest (name=0x7fffffffbce0 "PATH") at executables.c:100
100 dest[i] = malloc(srclen+1);
在瓦尔格林:
==21574== 1 errors in context 2 of 3:
==21574== Use of uninitialised value of size 8
==21574== at 0x400EB0: dest (executables.c:100)
==21574== by 0x400B5B: main (main.c:9)
这是我的职责:
char** dest(char *name){
int i=0;
char *vp;
const char s[2]=":";
char *token;
char **dest;
name[strlen(name)-1]='\0';
vp=getenv(name);
if(vp == NULL){
exit(1);
}
token =strtok(vp,s);
while( token != NULL ){
size_t srclen = strlen(token);
dest[i] = malloc(srclen+1);
strcpy(dest[i], token);
token = strtok(NULL, s);
i++;
}
dest[i]=NULL;
return dest;
}
这是我的主题:
#include "executables.h"
int main(int argc, char **argv){
char *path;
char name[BUFSIZ];
printf("enter name of environment variable:\n");
fgets(name,BUFSIZ,stdin);
char **p=dest(name);
int j=0;
while(p[j]!=NULL){
printf("%s\n",p[j]);
j++;
}
return(0);
}
最佳答案
使用strdup()。保存步骤(说明
“\0”也是)你必须在动手之前分配一些内存,以便使用这种方法。否则,您可能需要一个链接列表并分配数据包,而不是使用数组模式。当你说dest[i] = <ptr value>
你正在索引一个未分配内存的偏移量,并存储一些东西,所以它是一个Sigvio。
#include <string.h>
#define MAXTOKENS 10000
char **get_dest(char *name) {
// Since dest has to be exposed/persist beyond this function all
// need dynamically allocate (malloc()) rather than stack allocate
// of the form of: char *dest[MAXTOKENS].
char *dest = malloc(MAXTOKENS * sizeof (char *)); // <--- need to allocate storage for the pointers
char *vp;
if ((vp = getenv(name)) == NULL)
exit(-1); // -1 is err exit on UNIX, 0 is success
int i = 0;
char *token = strtok(vp, ":");
while (token != NULL) {
dest[i] = strdup(token); // <=== strdup()
token = strtok(NULL, ":");
i++;
}
// dest[i] = NULL; // Why are you setting this to NULL after adding token?
return dest;
}
最好是main()负责将以空结尾的字符串传递给get_dest()函数,因为main是finicky fgets()的处理位置一般来说,你想在当地做一些最有意义、最相关的事情。如果您曾经使用get_dest()函数并在fgets()未读取字符串的地方使用它,那么在那里重写终止符将是一个浪费的步骤。因此,通过在fgets()之前将char数组初始化为零,您不必担心将尾部字节设置为'\0'。
最后,让函数名dest与它返回的变量名dest同名可能不太好在某些情况下,程序中有多个同名符号可能会给您带来麻烦。
#include "executables.h"
int main(int argc, char **argv) {
char *path;
char name[BUFSIZ] = { 0 }; // You could initialize it to zero this way
printf("enter name of environment variable:\n");
// bzero(name, BUFSIZ); //... or you could initialize it to zero this way then
fgets(name, BUFSIZ, stdin);
char **p = get_dest(name);
int j = 0;
while(p[j] != NULL) {
printf("%s\n", p[j]);
j++;
free(p[j]); // like malloc(), strdup'd() strings must be free'd when done
}
free(p);
return 0;
}
关于c - C程序中的段错误,malloc调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41971159/