요약:malloc.c:3074 - 이 코드가 오류를 일으키는 이유는 무엇입니까?
-
13-09-2019 - |
문제
아래 첨부된 C 코드를 실행하면 오류가 발생합니다.
summary: malloc.c:3074: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
malloc(21)에 대한 모든 호출마다;(아래 참조).누군가 이유를 설명해 주시겠습니까 ??제가 생각할 수 있는 모든 가능한 방법을 시도했지만 여전히 실패합니다.
파일:요약.c
/*
* File: summary.c
* Author: Maxim Veksler
*
* Created on December 4, 2009, 3:09 AM
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "manipulation.h"
/*
* Main for Maman 12, task 1 : Array summary utility
*/
int main(int argc, char** argv) {
/*STUB*/
char str[100];
strcpy(str, "3 5 234 11 77 44 5");
/*STUB*/
int resultsSize;
int* results;
int* aggregated;
results = parseInput(str, &resultsSize);
aggregatedArray((int*)NULL, (int)NULL);
return 0;
}
파일 조작.c
/*
* File: manipulation.c
* Author: Maxim Veksler
*
* Created on December 4, 2009, 3:09 AM
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
* Parse the input from user, dynamically allocate memory to the maximum
* possible requirment. Then convert the array of string tokens into an
* simple array of integers.
*/
int* parseInput(char* input, int* nOfResults) {
/* Allocate memory by the maximum possibly required size for int... */
int *results = (int*) malloc(strlen(input));
int* insertIterator = results;
char* pch;
/* We trash the user input, but it's cool - Worthless as usual. */
pch = strtok(input,"\t ,.-");
*nOfResults = 0;
while(pch != NULL) {
(*nOfResults)++;
*insertIterator = atoi(pch);
insertIterator++;
pch = strtok(NULL, "\t ,.-");
}
return results;
}
/*
* Summary the values given in the int array and return adress to new array
* containing an increasin sum of the values.
*/
int* aggregatedArray(int* inputArray, int size) {
int* results;
malloc(20);
malloc(21);
}
편집하다 이 코드는 문제를 보여주기 위해 여기에 가져온 간단한 버전이라는 점을 고려하세요.관련 없는 부분은 모두 삭제했습니다.
해결책
편집하다: 와, 방금 당신의 코드에 아주 나쁜 논리 오류가 있다는 것을 깨달았습니다.이것은 단지 누출이 아니라 버퍼 오버플로도 발생합니다!
int *results = (int*) malloc(strlen(input));
할당하는 것입니다 18바이트 (입력 길이) 이를 배열처럼 처리합니다. int
의, 이는 당신이 적합할 수 있다는 것을 의미합니다 18 / sizeof(int)
int
그 안에 있어요.일반적인 x86 크기를 가정하면 (18 / 4) == 4.5 정수만 맞출 수 있습니다!나중에 코드는 그보다 더 많은 것을 배열에 기록합니다.큰 오류입니다.
문제를 해결하려면 다음을 사용해야 합니다. realloc
.이 같은:
int *results = malloc(sizeof(int));
int result_size = 1;
int result_count = 0;
while(/*whatever*/) {
/* ok, i want to add an element to results */
if(result_count == result_size - 1) {
int *p = realloc(results, (result_size + 1) * sizeof(int));
if(!p) {
free(results);
return NULL; /* no more memory! */
}
results = p;
result_size++;
}
results[result_count++] = /*value*/
}
return results;
2개라서 유출이네 malloc
결과는 어디에도 저장되지 않습니다.이로 인해 다음이 불가능해집니다. free
해당 호출이 반환하는 포인터입니다.
사실 뭔진 잘 모르겠지만 aggregatedArray
실제로 하고 있어야 하는데 지금은 아무것도 하지 않습니다. 하지만 새다.
또한, 당신은 results = parseInput(str, &resultsSize);
어디 parseInput
반환합니다 malloc
에드 포인터.당신은 free(results);
나중에 더 이상 필요하지 않을 때(아마도 aggregatedArray
부르다).
마지막으로, 참고 사항으로.나는 그것을 짐작할 것이다 aggregatedArray((int*)NULL, (int)NULL);
실제로 그래야 한다 aggregatedArray(results, resultsSize);
:-피.
다른 팁
다음 명령문은 18바이트의 메모리를 할당합니다("3 5 234 11 77 44 5").
int *results = (int*) malloc(strlen(input));
하지만 당신은 그 메모리 영역에 정수를 넣고 있습니다 ...그래서 모든 공간을 다 써버리면 오래 가지 못할 것입니다...그러므로 그렇게 하는 것은 확실히 잘못된 것입니다.
더 나아가..free() 호출을 모두 사용하지 않고 있습니다..그럼 그것도 문제겠지..
"aggregatedArray" 함수에서는 나중에 해제될 수 있도록 malloc에서 반환된 포인터를 변수에 할당하지 않습니다.그들은 우주에서 길을 잃었습니다!