GDB 告诉我第 52 行导致了段错误。我不明白为什么。我正在实现一个简单的堆栈。它有两个功能:弹出和推送。看来 pop 不起作用。 pop 的目的是检索堆栈中最顶层的值。但是,当它尝试这样做时,我遇到了段错误。有谁知道原因吗?
/*************************************************************************
* stack.c
*
* Implements a simple stack structure for char* s.
************************************************************************/
// for strdup() in the testing code
#define _XOPEN_SOURCE 500
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// the capacity of the stack
#define CAPACITY 10
//global variable used to keep track of pop and push
typedef struct
{
// storage for the elements in the stack
char* strings[CAPACITY];
// the number of elements currently in the stack
int size;
}stack;
// declare a stack (as a global variable)
stack s;
/**
* Puts a new element into the stack onto the "top" of the data structure
* so that it will be retrived prior to the elements already in the stack.
*/
bool push(char* str)
{
s.strings[s.size++] = strdup(str);
return false;
}
/**
* Retrieves ("pops") the last ("top") element off of the stack, following
* the "last-in, first-out" (LIFO) ordering of the data structure. Reduces
* the size of the stack.
*/
char* pop(void)
{
char *ptr = s.strings[--s.size];
s.strings[s.size] = NULL;
return ptr;
}
/**
* Implements some simple test code for our stack
*/
int main(void)
{
// initialize the stack
s.size = 0;
printf("Pushing %d strings onto the stack...", CAPACITY);
for (int i = 0; i < CAPACITY; i++)
{
char str[12];
sprintf(str, "%d", i);
push(strdup(str));
}
printf("done!\n");
printf("Making sure that the stack size is indeed %d...", CAPACITY);
assert(s.size == CAPACITY);
printf("good!\n");
printf("Making sure that push() now returns false...");
assert(!push("too much!"));
printf("good!\n");
printf("Popping everything off of the stack...");
char* str_array[CAPACITY];
for (int i = 0; i < CAPACITY; i++)
{
str_array[i] = pop();
}
printf("done!\n");
printf("Making sure that pop() returned values in LIFO order...");
for (int i = 0; i < CAPACITY; i++)
{
char str[12];
sprintf(str, "%d", CAPACITY - i - 1);
assert(strcmp(str_array[i], str) == 0);
free(str_array[i]);
}
printf("good!\n");
printf("Making sure that the stack is now empty...");
assert(s.size == 0);
printf("good!\n");
printf("Making sure that pop() now returns NULL...");
assert(pop() == NULL);
printf("good!\n");
printf("\n********\nSuccess!\n********\n");
return 0;
}
最佳答案
看看这个:
printf("Making sure that push() now returns false...");
assert(!push("too much!"));
printf("good!\n");
在这里,您将字符串 "too much"压入已经满的堆栈。您的 push() 函数实际上并不检查您是否超出容量,它只是附加字符串。
bool push(char* str)
{
s.strings[s.size++] = strdup(str);
return false;
}
这意味着您将越过堆栈边界,破坏内存,将堆栈大小设置为 11,然后出现困惑。
也许推送功能应该做:
bool push(char* str)
{
if (s.size >= CAPACITY)
return false;
s.strings[s.size++] = strdup(str);
return true;
}
pop 函数需要做类似的检查,否则你最终可能会改变大小 堆栈,即使它是空的:
char* pop(void)
{
if (s.size == 0)
return NULL;
char *ptr = s.strings[--s.size];
s.strings[s.size] = NULL;
return ptr;
}
关于c - 如何修复从 C 中的函数传递指针的段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20188233/