2010-05-12 1 views
5

gcc 4.4.3 c89malloc char 배열에 액세스하는 스택 덤프

다음 소스 코드가 있습니다. 그리고 printf에서 스택 덤프를 얻는다.

char **devices; 
devices = malloc(10 * sizeof(char*)); 

strcpy(devices[0], "smxxxx1"); 

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */ 

나는이 같은 문자 배열을 만들어야한다고 생각하고 있습니다.

devices[0] 
devices[1] 
devices[2] 
devices[4] 
etc 

그리고 각 요소에 내 문자열을 저장할 수 있습니다. 당신은 포인터 (장치)를위한 공간을 할당하지만 한 ===

for(i = 0; i < 10; i++) 
{ 
    devices[i] = malloc(strlen("smxxxx1")+1); 
} 
+1

몇 가지 거의 동일한 답변을 유발하는 질문에 대한 명성. – sum1stolemyname

+0

스택 덤프 또는 코어 덤프? –

+0

@Matt Curtis : gcc에서 생성 한 프로그램 중 Win32 용 스택 덤프 생성 프로그램이 몇 가지 유형의 오류가있을 때 실행 된 DOS 상자를 기억합니다. 비록 현재의 설정에서 그렇게하지 않는 것 같습니다 (mingw, vista, x86-32). – nategoose

답변

5

포인터 배열에 대한 메모리를 할당했습니다. 문자열을 저장할 각 요소의 메모리를 할당해야합니다.

예 :

#define NUM_ELEMENTS 10 
char **devices; 
devices = malloc(NUM_ELEMENTS * sizeof(char*)); 

for (int i = 0; i < NUM_ELEMENTS; i++) 
{ 
    devices[i] = malloc(length_of string + 1); 
} 
+0

NUM_ELELENTS를 소개하고 여전히 malloc() 호출에서 10을 사용합니다. – sharptooth

1

제안에 대한

많은 감사,

== 추가 보정은 가게에 가고 문자열을위한 공간을 할당하지 않았습니다.

2

문자 배열에 대한 포인터 배열 만 할당했습니다. 당신은 당신이 저장하려는 각 문자열에 대한 메모리를 할당해야합니다 : 10 문자 포인터를 저장하기위한

char **devices; 
devices = malloc(10 * sizeof(char*)); 

//Added this line: 

devices[0] = (char*)malloc(strlen("smxxxx1")+1); 
strcpy(devices[0], "smxxxx1\0"); 

printf("[ %s ]\n", devices[0]); /* Stack dump trying to print */ 
+2

문자열이 실제로'\ 0'을 명시 적으로 포함 할 필요가 없으며, 이미 null로 끝났습니다 – Hasturkun

+0

여분의 예방책으로 궁금합니다. 실제 char 배열이 NULL로 종료되어야 하는가? 10 가지 요소가 있습니다. 그러나 10 번째는 NULL이어야합니다. 이것은 표시를 반복하면서 NULL에서 멈추고 싶을 때를위한 것입니다. 고마워요. – ant2009

+1

@robUK : 배열 끝에서 NULL을 sentinel 값으로 사용하는 것은 때로는 일반적인 방법입니다 (예 : argv). 그것은 상황에 달려 있습니다. 때로는 센티널로 사용할 수있는 적절한 값이 없을 수도 있습니다 (NULL이 배열의 합법적 인 요소라면? 포인터의 배열을 다루지 않는다면 어떨까요?). – jamesdlin

3

당신은 할당 된 메모리를. 이러한 메모리 위치에 문자열을 저장하려면 각각의 메모리를 할당해야합니다. 기본적으로 포인터마다 device[0] = malloc(stringLen + 1);과 같은 것이 필요합니다.

4

장치는 [0] char *,하지만 당신은 그것을위한 모든 스토리지를 할당하지 않았습니다.

char **devices; 
devices = malloc(10 * sizeof(char*)); 

devices[0] = strdup("smxxxx1"); 

printf("[ %s ]\n", devices[0]); 

결국, 당신은 strdup()에 의해 할당 된 메모리를 해제해야합니다 : 대신 이렇게

free(devices[0]); 
0

장치 것은 포인터의 배열입니다. 요소 0이 문자열을 가리 키도록 설정하려는 경우 "smxxxx1"문자열 이상의 배열에 복사하는 것입니다. 대신 strcpy와의

는() 시도 :

devices[0] = "smxxxx1" 

또는

devices[0] = strdup("smxxxx1") 

편집 : 32 비트 시스템

, 장치 [0] 4 바이트로 구성된다 . 이 4 바이트는 문자열 "smxxxx1"의 처음 네 문자의 바이트 값으로 덮어 쓰여집니다. ascii에서 이들은 0x73, 0x6D, 0x78, 0x78입니다. little-endian 주소 지정을 가정하면 주소 0x78786D73에 대한 포인터를 포함하는 [0] 장치로 끝납니다. 이 주소는 프로세스 내에서 유효하지 않을 것입니다. printf()에 대한 호출이이 유효하지 않은 포인터를 참조 해제하려고 할 때 OS는 세그먼테이션 오류를 발생시키고 코어를 덤프합니다.

문제는 OP가 장치 변수를 초기화 할 때 문자열 (char 배열)로 잘못 취급하고 있다는 것이 었습니다. 실제로는 의 포인터을 char에 배열하고 printf()는이를 해석합니다.

+0

OP 배열이 const에 대한 포인터 인 경우이를 upvote 것입니다. –

+0

제한이 적절하지 않습니다. 그것의 언어 개념. 스택 덤프는 OS에 의해 트리거됩니다. –

+0

확실한 constness는 언어 개념이지만 컴파일러가 런타임시 커널 함정을 얻는 것보다 const에 대한 포인터를 통해 작성하는 것을 막을 것입니다. –