문제
다음 코드를 사용하면 매우 이상한 결과를 얻습니다. 마지막 요소의 값이 이전의 모든 배열 요소를 덮어 쓰는 이유는 무엇입니까? 이 Immmediate 문제보다 더 큰 문제가 있다고 생각합니다.
#include <stdio.h>
main()
{
int i, cases;
char num[1000000];
scanf("%d", &cases);
char* array[cases];
//store inputs in array
for(i=0; i<cases; i++)
{
scanf("%s", &num);
array[i] = #
}
//print out array items and their memory addresses
for(i=0; i<cases; i++)
{
printf("%d %s\n", i, array[i]); //print (array index) (array value)
printf("%d %p\n", i, &array[i]); //print (array index) (array address)
}
}
Inputs:
3 <-- number of lines to follow
0 <-- put in array[0]
1 <-- put in array[1]
2 <-- put in array[2]
Outputs
0 3 <-- why is this being overwritten with the last element?
0 0013BCD0
1 3 <-- why is this being overwritten with the last element?
1 0013BCD4
2 3
2 0013BCD8
올바른 솔루션이 없습니다
다른 팁
여기의 상향은 선입니다 array[i] = #
당신은 값을 설정합니다 array[i]
주소의 요소 num
정렬; ~부터 array
숯불 배열, 나는 그것이 당신의 num
배열 주소, 저차 바이트는 3입니다.
하지만. 즉, 당신의 Char Num [1000000]은 끔찍한 형태이며, 그렇게해서는 안됩니다. 힙에 할당하고 하늘을 위해 더 적은 숫자를 선택하십시오. 또한 Scanf ( "%S", & num)는 실제로 원하는 것을 제공하지 않습니다. 여기에 힌트가 있습니다. getc () 루프를 사용하여 숫자를 읽습니다. 이것은 scanf ()에 대한 배열의 preallocation을 수행 할 필요가 없습니다.
배열의 모든 색인을 동일한 주소 (char num [10000000];)에 넣기 때문입니다.
동적 할당 (Calloc, Malloc, New 등)으로 이어지는 오류입니다.
건배!
첫 번째 루프 내부에서는 각 입력을 NUM 배열의 다른 요소로 작성해야합니다. 대신 당신은 항상 같은 장소에 글을 쓰고 있습니다. &num
.
char* 배열 [cases];
이것은 런타임이 아닌 컴파일 타임에 할당됩니다. 그리고 사례는 초기화되지 않았지만 (어쨌든 역동적으로 작동하기를 원한다고 생각하지만) 메모리를 사전화하거나 Malloc 라이브러리 기능에 익숙해 져야합니다.
바꾸다
//store inputs in array
for(i=0; i<cases; i++)
{
scanf("%s", &num);
array[i] = #
}
~와 함께
array[0] = num;
//store inputs in array
for(i=0; i<cases; i++)
{
scanf("%s", array[i]);
array[i+1] = array[i] + strlen(array[i]) + 1;
}
각 문자열이 사용 가능한 첫 번째 공간으로 스캔하려면 num[]
, 다음 요소를 설정하십시오 array[]
다음 공간을 가리키기 위해. 이제 당신의 printf()
문자열의 작동이 작동합니다. 원본은 모든 문자열을 시작으로 스캔했습니다. num[]
.
메모: scanf()
도로와 함께 %s
만큼 나쁘다 gets()
, 그것은 때려지는 데이터의 양을 제한하지 않기 때문에. 실제 코드에서 사용하지 마십시오.
바꾸다
printf("%d %p\n", i, &array[i]); //print (array index) (array address)
~와 함께
printf("%d %p\n", i, (void*)(array[i])); //print (array index) (array address)
저장된 주소를 실제로 인쇄합니다 a[]
, 요소의 주소보다는 a[]
. 캐스트는 필요합니다 %p
포인터로 기대합니다void
따라서 하나를 제공해야합니다.
그게 고정 된 코드 :
#include <stdio.h>
main(void)
{
int i, cases;
scanf("%d", &cases);
char* array[cases];
//store inputs in array
for(i=0; i<cases; i++)
{
char *num = malloc(100000);
scanf("%s", num);
array[i] = num;
}
//print out array items and their memory addresses
for(i=0; i<cases; i++)
{
printf("%d %s\n", i, array[i]); //print (array index) (array value)
printf("%d %p\n", i, (void*)&array[i]); //print (array index) (array address)
}
return 1;
}
당신은 또한 사용할 수 있습니다
char *num = calloc(100000, sizeof(char));
조금 방어 적입니다. 왜 100000이 필요한지 모르겠습니다. Malloc을 사용하여 동적으로 수행 할 수 있습니다. 여기에는 더 많은 작업이 포함되지만 매우 강력합니다.
코드에서 모호한 것은 문자열 %s를 변경하지 않는 NUM의 주소에 저장 한 다음 해당 주소에 배열 [i] 요소를 할당한다는 것입니다. C로 할당하는 것은 참조를 저장하는 것이 아닙니다. 요소 자체를 저장하지 않습니다. 이것은 공간 낭비입니다. 따라서 모든 배열 요소가 주소를 가리키면 (참조 만 저장), 참조의 값은 참조도 변경되므로 모두 2로 변경되는 이유 (게시물에 명시된대로 3이 아님).
C ++가 만들어지는 것 같습니다. 사용자 입력 구문 분석 및 동적 할당은보다 안전하고 산들 바람으로 이루어집니다. C ++로 전환 할 수없는 사용자 인터페이스가있는 시스템을 생각할 수 없습니다.
물론, 이것이 문제로 고통받는 다른 코드에서 발췌 한 테스트 일 뿐이라면 물론 ...
귀하의 코드는 C 초보자에 대한 몇 가지 일반적인 실수와 요즘 그렇게해서는 안되는 일로 고통 받고 있습니다.
내가 올바르게 이해하면 Sereval 사용자 입력 문자열을 저장하려고합니다 (예제 출력은 숫자 만 표시하기 때문에 약간 오도됩니다).
당신은 모든 (케이스 카운트) 포인터를 문자열에 고정시키기 위해 배열을 준비하고 있지만, 하나의 문자열에 대한 메모리 만 예약하고 있습니다. 모든 문자열에 대해 그렇게해야하므로 케이스가 필요합니다. "동적 메모리 할당"레슨 측면에서 물건을 간단하게 유지하려면 그렇게하는 것이 좋습니다. char* array[cases][10000];
그것은 당신에게 10k 문자의 문자열을 제공합니다.
당신은 아마 배열 요소에 별도의 포인터를 갖고 싶지 않을 것입니다. 해당 요소가 포인터 자체보다 큰 경우 배열의 요소를 정렬하려면 이는 의미가 있습니다. 이 경우 성능의 이득은 큰 덩어리를 이동 (복사)하는 것이 아니라 포인터 (보통 4 바이트) 만 이동해야합니다. 귀하의 경우 int는 4 바이트 길이입니다. 그리고 당신은 어쨌든 정렬하지 않습니다 :)
scanf()
가장 말하는 것은 위험합니다. 두 번째 응용 프로그램에서는 배열 주소에 문자열을 쓰도록 지시합니다. 이것은 단순한 실수 인 것처럼 보이지만 많은 문제를 일으킬 수 있습니다. 당신은 아마 그렇게하고 싶을 것입니다 : scanf("%d", &array[i]);
(불행히도, 나는 컴파일러가 없으므로 100% 확실하지 않습니다). 다음 줄을 떨어 뜨립니다 :)
Markdown 전문가에게 질문 : 코드 블록과 목록을 결합하는 것이 왜 그렇게 불가능합니까?