저는 C로 스택을 구현하는 동시에 C를 배우려고 노력하고 있습니다. 제 배경은 대부분 고등 언어 (예 : Python)에 있으므로 많은 메모리 할당이 저에게 새로운 것입니다.
예상대로 작동하는 프로그램이 있지만 내가 뭔가 잘못하고 있다고 믿게 만드는 경고를 표시합니다.
다음은 코드입니다.
typedef struct {
int num_items;
int top;
int items[];
} stack;
void push(stack *st, int n) {
st->num_items++;
int* tmp = realloc(st->items, (st->num_items) * sizeof(int));
if (tmp) {
*(st->items) = tmp;
}
st->items[st->num_items - 1] = n;
st->top = n;
}
int main() {
stack *x = malloc(sizeof(x));
x->num_items = 0;
x->top = 0;
*(x->items) = malloc(0);
push(x, 2);
push(x, 3);
printf("Stack top: %d, length: %d.\n", x->top, x->num_items);
for (int i = 0; i < x->num_items; i++) {
free(&(x->items[i]));
}
free(x->items);
free(x);
}
출력은 다음과 같습니다.
Stack top: 3, length: 2.
어느 것이 예상됩니다. 그러나 컴파일 중에 다음과 같은 오류가 발생합니다.
> gcc -x c -o driver driver.c
driver.c: In function 'push':
driver.c:16:16: warning: assignment makes integer from pointer without a cast
*(st->items) = tmp;
...
driver.c: In function 'main':
driver.c:27:14: warning: assignment makes integer from pointer without a cast
*(x->items) = malloc(0);
당신의 믿음이 맞습니다. 일반적으로 거의 항상 그렇습니다. C 컴파일러의 경고는 심각한 문제를 일으킬 수있는 심각한 프로그래밍 오류의 신호입니다. 다양한 프로그래밍 언어로 발에 자신을 쏘아 올리기 :
씨
- 당신은 발에 총을 쏜다.
- 당신은 발에 총을 쏘면 아무도 당신이 한 일을 알아낼 수 없습니다.
문제는 int items
에 대한 포인터 처럼 코딩하고 있지만 완전히 다른 짐승 인 FAM ( Flexible Array Member) 으로 선언하고 정의 했다는 것 입니다. 그리고 이후 배열에 할당하는 오류가 발생 것 , 즉
x->items = malloc(0);
오류가 될 수 있으며 경고만으로 컴파일되는 무언가를 생각해 냈습니다. 오류는 경고보다 낫다는 것을 기억하십시오.
해결책은 대신에 items
대한 포인터로int
선언 하는 것입니다.
int *items;
그리고 사용
x->items = ...;
기대하는 포인터 동작을 얻으려면.
또한,
free(&(x->items[i]));
i
첫 번째 정수를 할당하지 않았기 때문에 매우 잘못 되었습니다. 그들은 배열의 객체였습니다. 또한 필요하지 않습니다 malloc(0)
. null 포인터로 초기화하십시오.
x->items = NULL;
realloc
그리고 free
널 포인터는 신경 쓰지 않을 것입니다.
유연한 배열 구성원은 구조의 마지막 요소가 무한 길이의 배열이므로 malloc
충분한 메모리를 예약 할 수 있음을 의미합니다.
stack *x = malloc(sizeof x + sizeof *x->items * n_items);
가요 어레이 구성원과 같은 개체의 CPython에서 사용되는 str
, bytes
또는 tuple
불변 길이 있는지 -이 다른 포인터 대신 FAM을 사용하여 약간 빠르며, 그것은 메모리에 저장 - 특히 짧은 문자열 또는 튜플.
마지막으로, 스택이 커질수록 느려집니다. 그 이유는 항상 하나의 요소 만 더 할당하기 때문입니다. 대신 삽입이 시간 내에 실행되도록 인수 (1.3, 1.5, 2.0?)로 스택의 크기를 조정해야 O(1)
합니다 O(n)
. 그리고 어떤 일이 일어날 지 생각해보십시오. realloc
아마도 당신은 그것에 대해 더 크게해야합니다!
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다