경로 목록 (환경 변수)을 가져와 경로를 분할하여 인쇄하는 프로그램을 작성 중입니다. 그것을 컴파일 할 때 나는 segfault를 얻습니다. 다음은 GDB의 출력입니다.
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400eb0 in dest (name=0x7fffffffbce0 "PATH") at executables.c:100
100 dest[i] = malloc(srclen+1);
valgrind에서 :
==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>
할당되지 않은 메모리가 저장 뭔가의 오프셋 당신에게있는 거 색인을, 그래서 그것은 segvio입니다.
#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 ()이 적절한 null로 끝나는 문자열을 get_dest () 함수에 전달하는 것이 더 좋습니다. main은 까다로운 fgets ()가 처리되는 곳이기 때문입니다. 일반적으로 가장 의미 있고 가장 관련성이 높은 곳에서 작업을 수행하려고합니다. get_dest () 함수를 가져 와서 fgets ()가 문자열을 읽지 않은 곳에서 사용했다면 거기에서 종결자를 덮어 쓰는 것은 낭비 일 것입니다. 따라서 fgets () 전에 char 배열을 0으로 초기화하면 후행 바이트를 '\ 0'으로 설정하는 것에 대해 걱정할 필요가 없습니다.
그리고 마지막으로 함수 이름이 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;
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다