문제

그래서 C 코드:

#include <stdio.h>
#include <string.h>

/* putting one of the "char*"s here causes a segfault */
void main() {
  char* path = "/temp";
  char* temp;
  strcpy(temp, path);
}

이 컴파일하고,실행,그리고 행동으로 보인다.그러나는 경우,한쪽 또는 양쪽의 문자를 포인터로 선언한 글로벌 변수,strcpy 결과에 segmentation fault.그 이유는 무엇입니까?분명히 있의 오류에 대한 이해의 범위가 있습니다.

도움이 되었습니까?

해결책

다른 포스터가 언급 한 바와 같이, 문제의 근본은 온도가 초기화되지 않았다는 것입니다. 스택에서 자동 변수로 선언하면 해당 메모리 위치에있는 쓰레기가 포함되어 있습니다. 실행중인 컴파일러+CPU+OS의 경우 해당 위치의 쓰레기는 유효한 포인터입니다. strcpy는 segfault가 아니라는 점에서 "성공"하지만 실제로는 메모리의 다른 어느 곳에서나 임의의 위치에 문자열을 복사했습니다. 이런 종류의 기억 부패 문제는 디버깅하기가 매우 어렵 기 때문에 C 프로그래머의 마음에 두려워합니다.

임시 변수 선언을 글로벌 범위로 이동하면 BSS 섹션에 배치되어 자동으로 제로화됩니다. *임시 피해를 시도하면 segfault가 발생합니다.

*경로를 글로벌 범위로 이동하면 *온도가 스택의 한 위치를 올라갑니다. 해당 위치의 쓰레기는 분명히 유효한 포인터가 아니므로 불쾌한 *온도로 인해 Segfault가 발생합니다.

다른 팁

임시 변수는 스토리지 (메모리)를 가리키지 않으며 초기화되지 않습니다.

임시로 선언 된 경우 char temp[32]; 그러면 코드가 어디에서 선언 하든지 작동합니다. 그러나 고정 된 크기로 온도를 선언하는 데 다른 문제가 있지만 다른 날에는 문제입니다.

이제, 전 세계적으로 선언 될 때 왜 현지가 아닌지가 충돌합니까? 운...

로컬로 선언하면 그 당시에는 스택에 값이있을 수있는 값에서 온도의 가치가 나옵니다. 충돌을 일으키지 않는 주소를 가리키는 것은 운이 좋다. 그러나 다른 사람이 사용하는 메모리를 쓰레기로 작성합니다.

전 세계적으로 선언되면 대부분의 프로세서에서 이러한 변수는 Demand Zero Pages를 사용할 데이터 세그먼트에 저장됩니다. 따라서 char *temp 마치 선언 된 것처럼 보입니다 char *temp=0.

온도를 할당하고 초기화하는 것을 잊었습니다.

temp = (char *)malloc(TEMP_SIZE);

temp_size가 충분히 커지는 지 확인하십시오. 런타임에 이것을 계산 한 다음 크기가 충분한 지 확인할 수 있습니다 (최소한 strlen (경로)이어야합니다).

위에서 언급했듯이 온도 공간을 할당하는 것을 잊었습니다. 나는 선호한다 strdup 에게 malloc+strcpy. 그것은 당신이하고 싶은 일을합니다.

아니요 - 변수에 관계없이 작동하지 않습니다. 운이 좋았 기 때문에 그랬던 것처럼 보입니다. 변수를 초기화되지 않은 상태로 두지 않고 문자열의 내용을 저장하기 위해 공간을 할당해야합니다.

스택의 비 초기 변수는 거의 무작위 메모리 위치를 가리키고 있습니다. 이러한 주소가 유효한 경우 코드는 무엇이든 모든 것을 짓밟지만 오류가 발생하지는 않지만 코드의 다른 곳에서는 불쾌한 메모리 손상 관련 버그가 발생할 수 있습니다).

글로벌은 일반적으로 메모리를 가리키는 특정 패턴으로 설정되기 때문에 일관되게 실패합니다. 이것들을 피하려고 시도하면 즉시 segfault를 제공합니다 (나중에 나중에 남겨 두는 것이 더 좋을 것입니다. 버그를 추적하기가 매우 어렵습니다).

첫 번째 Adam의 조각을 다시 작성하고 싶습니다

// Make temp a static array of 256 chars
char temp[256];
strncpy(temp, sizeof(temp), path);
temp[sizeof(temp)-1] = '\0';

그렇게하면 당신 :

1. don't have magic numbers laced through the code, and
2. you guarantee that your string is null terminated.

두 번째 포인트는 소스 문자열의 마지막 숯을 잃어버린 것입니다.

주목할 중요한 부분 :
목적지 문자열 dest는 사본을받을 수있을 정도로 커야합니다.
귀하의 상황에서 온도에는 복사 할 메모리가 할당되지 않았습니다.

strcpy의 남자 페이지에서 복사 :

DESCRIPTION
   The  strcpy()  function  copies the string pointed to by src (including
   the terminating '\0' character) to the array pointed to by  dest.   The
   strings  may not overlap, and the destination string dest must be large
   enough to receive the copy.

당신을 호출하는 정의되지 않은 행동 때문에,당신이하지 않을 초기화 temp 변수가 있습니다.그것은 임의의 위치에서 메모리,그래서 당신의 프로그램 일,하지만 대부분 그것은 세그멘테이션.당신이 필요하의 대상자를 배열하거나,그것은 포인트를 동적 메모리:

// Make temp a static array of 256 chars
char temp[256];
strncpy(temp, 256, path);

// Or, use dynamic memory
char *temp = (char *)malloc(256);
strncpy(temp, 256, path);

또한,사용 strncpy()strcpy() 피 버퍼를 초과.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top