2012-06-28 3 views
3

첫 번째 질문은 여기에 있습니다. 2D 배열 대신 포인터 배열을 사용하고 있습니다. 이제 요소를 표시하려면 * (arr [i] + j)를 사용할 수 있습니다. 여기서 arr은 배열이고 i는 행을 나타내며 j는 열을 나타냅니다. 그러나 동일한 표기법을 사용하는 요소에 값을 할당하려고하면 코드가 작동을 멈 춥니 다. 컴파일 오류가 발생하지 않지만 실행하면 작동이 멈 춥니 다. 아무도 나를 도울 수 있습니까?포인터 배열 사용

여기에 내 코드

당신은 문자열 리터럴을 수정하려고
#include <stdio.h> 
#include <conio.h> 
#include <string.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int i,j,k; 
    char temp2, temp, *arr[] = { 
     "Brinda Roy", 
     "Rakesh Bai", 
     "Neha Saxen", 
     "Ankit Jain"}; 

    printf("%c",*(arr[3]+8)); 

    for(i=0;i<4;i++){ 
     for(j=0, k=9; j<=4, k>=5; j++, k--){ 
      temp =*(arr[i]+j); 
      *(arr[i]+j)=*(arr[i]+k); 
      *(arr[i]+k)=temp; 
     } 

    } 

    printf("\nThe array is "); 

    for(i=0; i<4; i++){ 
     printf("\n%s",arr[i]); 
    } 

    getch(); 
    return 0; 
} 
+0

디버거를 열고 문제가 발생하면 카운터의 값을 검사하십시오. 문제가 무엇인지는 매우 분명하게 알 수 있습니다. –

+2

포인터 배열은 2D 배열입니다. 'arr [i]'는'* (arr + i)'와 같습니다. – Trevor

+0

오류가 세그먼트 오류 오류 일 수 있습니다. 즉 배열이 어딘가에 경계를 벗어 났음을 의미합니다. 일반적으로 포인터로 놀 때 발생합니다. 코드 디버깅을 시도하십시오. – ppsreejith

답변

2

입니다. 이것은 금지되어 있습니다. 형식 시스템 ("abc"const char*이 아님)에 의해 시행되지는 않지만 문자 리터럴 "abc"[1]='c'을 수정하면 정의되지 않은 동작이 발생합니다.

쓰기 가능한 위치로 데이터를 이동해야합니다.

for(i=0; i<4; i++) 
    arr[i]=strdup(arr[i]); 

문자열의 힙에 메모리를 할당하고 여기에 문자열을 복사합니다 :이 일을하는 가장 쉬운 그러나 비표준 방법은 strdup 기능을 사용하는 것입니다. strdup 기능이없는 경우 malloc, strlenmemcpy을 사용하여 구현해야합니다.

항상 동적으로 할당 된 메모리와 마찬가지로 메모리를 확보해야합니다. 그렇지 않으면 메모리 누수가 발생합니다.

현재 이중 포인터 배열과 다차원 배열에 모두 액세스하는 일반적인 방법은 arr[i][j]입니다.

+0

도움 주셔서 감사합니다. 포인터의 배열을 연습하기를 원했기 때문에 모든 2D 배열 코드를 포인터 배열로 수정하려고했습니다. arr [i] [j] 표기법에 대해 알고 있습니다. 문자열 리터럴에 대해 알지 못했습니다. 감사합니다 – Swapnil

5

런타임 리터럴이 문자열 리터럴을 arr으로 수정했기 때문입니다. 문자열 리터럴 "Brinda Roy", "Rakesh Bai", "Neha Saxen""Ankit Jain"은 프로그램의 읽기 전용 섹션에 저장 될 수 있으므로 const char[]으로 처리해야합니다. 값을 변경하려고하면 정의되지 않은 동작이 발생합니다 (아래 주석 참조).

이러한 읽기 전용 문자열을 편집하려면 버퍼를 const 개 버퍼에 복사해야합니다.


당신이 할 경우는 메모리를 읽기 전용으로 가리키는 있기 때문에

char *str = "message" 

당신은 데이터가 str가 가리키는 수정하면 안됩니다.


은 당신이 할 경우 읽기 전용 문자열 리터럴 "message" 배열 str복사을하고 있기 때문에

char str[] = "message" 

당신 수정할 수있는 데이터는 str에 의해 지적했다.


코드는 위의 첫 번째 시나리오에 해당합니다.

+2

약간의 nit, 문자열 리터럴은 읽기 전용 섹션에 저장할 수 있습니다. 그들에게 쓰는 것은 정의되지 않은 동작이며, 컴파일러는 쓰기 가능한 메모리에 자유롭게 둘 수 있습니다. – Michael

+0

@ 마이클 : 그래, 그게 더 좋은 방법이야. – AusCBloke

3

C는이 스타일을 통해 소스에 정의 된 문자열을 읽기 전용 데이터 섹션에 저장할 수 있습니다.이 출력을 확인하십시오

$ cat storage.c 
int main(int argc, char* argv[]) { 
    char *arr[] = {"hello", "world"}; 
    arr[1][1]='a'; 
    return 0; 
} 
$ make storage 
cc  storage.c -o storage 
$ readelf -p.rodata storage 

String dump of section '.rodata': 
    [  4] hello 
    [  a] world 

제 컴파일러는 .rodata 읽기 전용 데이터 섹션에 문자열을 배치했다. 나는이 프로그램에 ao를 업데이트하려고하면 프로그램이 죽으면 :

char *foo = "string"; 

당신이 원하는 경우 :이 일반적이다

$ ./storage 
Segmentation fault (core dumped) 

는 다음과 같은 문자열을 정의하는 코드에 적용 프로그램 소스에서 수정 문자열을 만들 때이 같은 대신 쓰기 것 :

char foo[] = "string"; 

을 내가 구문에 어떻게 될지 확실 전체 아니에요 수정 가능한 문자열의 배열을 만듭니다. 적어도 추한 접근 방식은 작동 다음,하지만 난 더 나은 뭔가있을거야 :

char a1[] = "hello"; 
char a2[] = "world"; 
char *arr[] = {a1, a2}; 
+0

아, 포인터 배열을 사용하는 대신 배열에 대한 포인터를 사용하면 문자열을 올바르게 수정할 수 있습니까? – Swapnil

+0

내 대답의 마지막 줄은 배열에 대한 포인터가 아니므로 포인터에 대한 배열을 작성한다는 점에 유의하십시오. – sarnold

+0

오, 그래. 너의 의도를 알 겠어. 그것을 시도하고 당신에게 돌아 가자. 편집 - 작동 중입니다. 감사. 그러나 각 문자열에 대해 별도의 배열을 선언하지 않는 방법이 있습니까? – Swapnil

1

당신은 메모리를 수정할 수 없습니다 이런 식으로 예약 : 당신이 문자를 정의 할 때

{"Brinda Roy", 
"Rakesh Bai", 
"Neha Saxen", 
"Ankit Jain"}; 

은 *이 방법 , 읽기 전용 메모리입니다.