【问题标题】:Pop in Stack is not popping?Pop in Stack 不弹出?
【发布时间】:2017-06-23 20:06:23
【问题描述】:

我的 pop 没有弹出,老师提供了这段代码的骨架,我输入了 printf 语句,并且推送似乎正在工作,它似乎在到达 pop 一词时停止了。我知道我可能没有正确释放内存,所以我想我稍后会修复它(或者这可能是问题所在?) char** 真的让我对这个感到失望。 这个问题和这个Conflicting types for enum bool?是一样的 我想我班上更多的人遇到了问题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
char** data;    /* Array of strings representing the stack */
int top;        /* Index of the top of the stack.  top is -1 if the stack is 
empty. */
int size;       /* Number of elements that the stack can currently hold */
} Stack;

typedef enum { FALSE, TRUE } bool;

/* function prototypes */
Stack* create();
void deleteStack( Stack* ps );
void push( Stack* ps, char* str );
char* pop( Stack* s);
bool empty( Stack *s );
bool full( Stack *s );

int main(int argc, char *argv[])
{
FILE *in_file = fopen("data_a2.txt", "r");
Stack *s;

printf("CS 2123 Assignment 2\n");

if (in_file == NULL)
{
    printf("File %s not found.\n", "data_a2.txt");
    return -1;
}
    char strBuffer[256];

    s = create();

    while(fscanf(in_file, "%s", strBuffer)!=EOF) {
        printf("%s\n", strBuffer);

        if(strcmp(strBuffer, "pop") == 0) {
            pop(s);
            } else {
                push(s, strBuffer);
            }
        }

   // free(s);



/* Uncomment next line once you get create working */
   // deleteStack( &s );
fclose(in_file);

}

/* create: returns a new empty stack. */
Stack* create(){
    Stack *s;
s = (Stack*)malloc(sizeof(Stack));
s->top = -1;
s->size = 10;
s->data = (char**)malloc(s->size * sizeof(char*));
return s;
}

/* deleteStack: deletes the memory associated with the given stack. */
void deleteStack( Stack* ps ){
while( ps->top>=0 ){
    free( ps->data[ps->top] );
    ps->top--;

}

free( ps->data );
}

/*
 *  push: takes a string parameter which is the value it pushes onto the 
 stack.
 *  It may also need to call realloc to expand the size of the stack before 
completing the push.
*/
void push( Stack* s, char* str ){
   char *newStr;
   newStr = (char*)malloc(256);
   strcpy(str, newStr);
if(full(s)){
    s->size = 10;
    s->data = (char**)realloc(s->data, s->size);
}
s->data[++s->top] = str;
free(newStr);
free(s->data);
//make new str malloc strcpy buffer
//realloc memory here s.data
}

/* pop: returns the string that was removed from the stack. */
char* pop( Stack* s){
    if(empty(s)) {
        return NULL;
    }
printf("# of elements after popping: %d, string popped: %s\n",s->top + 1, s-
>data[s->top]);
return s->data[s->top--];
}

/* empty: returns TRUE if the stack has no elements, otherwise FALSE. */
bool empty( Stack *s ){
if(s->top == -1) {
    return TRUE;
} 
return FALSE;
}

/* full returns TRUE if the stack does not have any room left, otherwise 
FALSE. */
bool full( Stack *s ){
    if (s->top == s->size - 1) {
        return TRUE;
}
return FALSE;
}

【问题讨论】:

  • printf里不应该是s-&gt;top - 1吗...
  • 你的 strcpy 参数被颠倒了。应该是strcpy(newstr, str)

标签: c stack


【解决方案1】:

我只看了push

问题:

  • 可怕的缩进。
  • 没有理由相信256 足以满足您的字符串要求。使用strlen(str)+1
  • strcpy(str, newStr) 应该是 strcpy(newStr, str)
  • strdup更方便。
  • s-&gt;size = 10; 应该是 s-&gt;size += 10;
  • 重新分配时,传递的是指针的数量,而不是它们占用的大小。
  • 强制转换realloc 的结果没有意义。 (malloc 也是如此。)
  • 您在堆栈中添加了 str 而不是 newStr
  • 不要释放你添加到堆栈中的字符串!
  • 不要释放堆栈!
  • 不检查内存分配错误。 (这在下面没有固定。)

固定:

void push( Stack* s, const char* str ) {
    if (full(s)) {
        s->size += 10;
        s->data = realloc(s->data, s->size * sizeof(char*));
    }

    s->data[++(s->top)] = strdup(str);
}

清理了其余的堆栈代码(没有解释):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char** data;  /* Array of strings representing the stack */
    int size;     /* Number of elements that the stack can currently hold */
    int top;      /* Index of the top of the stack (-1 if empty). */
} Stack;

Stack* Stack_new();
void   Stack_delete( Stack* ps );
void   Stack_push( Stack* ps, const char* str );
char*  Stack_pop( Stack* s );
int    Stack_empty( const Stack* s );
int    Stack_full( const Stack* s );

int main(int argc, char *argv[]) {
    Stack *s = Stack_new();

    ...
    Stack_push(s, str);
    ...

    ...
    char* str = Stack_pop(s);
    free(str);
    ...

    Stack_delete(s);
    return 0;
}

/* Create a new empty stack. */
Stack* Stack_new() {
    Stack* s = malloc(sizeof(Stack));
    s->top = -1;
    s->size = 10;
    s->data = malloc(s->size * sizeof(char*));
    return s;
}

/* Deletes the memory associated with the given stack. */
void Stack_delete( Stack* s ) {
    while ( s->top >= 0 ){
        free( s->data[(s->top)--] );
    }

    free( s->data );
    free( s );
}

/* Pushes a copy of the provided NUL-terminated string unto the stack. */
void Stack_push( Stack* s, const char* str ){
    if (full(s)) {
        s->size += 10;
        s->data = realloc(s->data, s->size * sizeof(char*));
    }

    s->data[++(s->top)] = strdup(str);
}

/* Returns the string that was removed from the stack. */
/* The returned string needs to be freed. */
/* Returns NULL if the stack is empty. */
char* Stack_pop( Stack* s ) {
    if (empty(s)) {
        return NULL;
    }

    return s->data[(s->top)--];
}

/* Returns true if the stack is empty. */
int Stack_empty( const Stack* s ) {
    return s->top == -1;
}

/* Returns true if the stack is full. */
int Stack_full( const Stack* s ) {
    return s->top == s->size - 1;
}

请注意,我没有添加内存分配错误检查。

【讨论】:

  • 这就是 valgrind 的用途,谢谢你修复它。这是我教授第二学期讲授数据结构。她的专长是算法。这个夏天会很艰难。谢谢!
  • Valgrind 什么也找不到。我的意思是我不检查strdupmallocrealloc 是否返回NULL(因为您的内存不足)。我想如果你的记忆力不足,无论如何你都搞砸了。
【解决方案2】:

我认为你让这个练习变得更复杂了。

你的推动:

void push( Stack* s, char* str ){
   char *newStr;
   newStr = (char*)malloc(256);
   strcpy(str, newStr);
if(full(s)){
    s->size = 10;
    s->data = (char**)realloc(s->data, s->size);
}
s->data[++s->top] = str;
free(newStr);
free(s->data);
//make new str malloc strcpy buffer
//realloc memory here s.data
}

它做的比要求的要多得多。 push 应该接受调用者定义的任何字符串(你的main()

比较:

Stack* create()
{
   Stack* stack = malloc(sizeof(Stack));
   if (!stack)
       return 0;
   stack->size = 128;    // or any size you like...
   stack->top = -1;
   stack->data = malloc(stack->size * sizeof(char*));
   if (!stack->data)
   {
       free(stack);
       return 0;
   }
   return stack;
}

bool push( Stack* ps, char* str )   // I would consider returning an error code
{
    char* str2;
    char** tmp;
    str2 = strdup(str);    // caller of pop() should call free()
    if (!str2)
        return FALSE;      // error condition
    if (full(ps)) {
        tmp = (char**)realloc(ps->data, (ps->size + 10) * sizeof(char*));
        if (!tmp)
            return FALSE;  // this is an error condition.
                           // use return value to inform the caller
        ps->size += 10;
        ps->data = tmp;
    }
    ps->data[++(ps->top)] = str2;  
    return TRUE;
}

【讨论】:

  • 也许返回一个布尔值来表示成功?
  • 我的理解是main()之前的一切都是教授提供的,定义了要执行的任务。
  • 即便如此,我认为教授不会反对解决这个问题,特别是因为它仍然可以像以前一样被调用。
【解决方案3】:

哇,这段代码有这么多问题,我不知道从哪里开始。

push 方法对我来说毫无意义,你传递一个字符串(它可能指向一个只读位置),你保留(相当随意)256 字节的内存,将这个新的未初始化数据复制到src 然后释放再次回忆……

你使用mallocrealloc真的很糟糕

int size = ???;
int *array = malloc(size * sizeof *array);

int new_size = ???;
int *tmp = realloc(array, new_size * sizeof *array);
if(tmp == NULL)
    // no more memory, array is still alive
    // return

array = tmp;

我不喜欢堆栈的整体设计,您应该设计数据结构,以便无需查看代码就可以清楚地知道您在做什么。给我几分钟,我会发布类似的内容。

编辑:

我收回我的例子,它的设计很糟糕。

【讨论】:

  • strcpy 是她的主意,当我寻求帮助时,她建议了它。这不像我在任何教科书或互联网上找到的任何堆栈结构。真是一团糟。
  • @slyalys,您使用数组构建了堆栈。 Pablo 使用链表构建了他们的。我不知道为什么
  • @ikegami 我知道这不是一个优雅的解决方案,有些人可能想为此用石头砸死我。我一直很喜欢链表,我想我可以更好地想象它们。
  • 链表是有用途的;它们甚至对于堆栈来说似乎很方便,但在我看来,节省的内存不仅仅是链接列表的开销所损失的。你也失去了性能。这不是一个很好的匹配。
  • 我同意你的看法。我喜欢它们的原因,特别是当有人开始学习复杂的数据结构时(至少对我来说)更容易可视化。使用数组和处理索引更有效,但需要一段时间才能完全理解,特别是当您是初学者时。这就是我选择链接链接方法的原因。
猜你喜欢
  • 2013-12-31
  • 2016-10-23
  • 2017-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2018-09-01
  • 2018-07-09
相关资源
最近更新 更多