2013-11-25 78 views
1

我正在创建一个具有推送和弹出功能的简单堆栈。我试图将一系列字符串推入一个充当内存堆栈的数组中。但是,GDB一直告诉我,我没有正确地将字符串复制到数组中。任何人有关于我如何解决这个问题的想法?如何将字符串复制到C中的数组?

/************************************************************************* 
* 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) 
{ 
    int i = 0; 
    s.strings[i++] = strdup(str); 
    ++s.size; 
    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) 
{ 
    int i = CAPACITY-1; 
    return s.strings[i--]; 
} 

/** 
* 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; 
} 
+1

以下两个答案都是正确运行所需的:-) – anishsane

+0

同意,两者都需要改变。但是,弹出功能仍然给我分段错误。不知道为什么... – KishB87

回答

1

POP()函数总是返回相同的字符串:

char* pop(void) 
{ 
    int i = CAPACITY-1; // i is the same! 
    return s.strings[i--]; // the same pointer 
} 

我想建议在将它更改为以下:

char* pop(void) 
{ 
    if (s.size == 0) return NULL; 
    char *str = s.strings[--s.size]; 
    s.strings[s.size] = NULL; 
    return str; 
} 

它避免了将过时的指针存储在堆栈中。

+0

嗯,有趣的一点,并感谢这一投入。我没有意识到这一点。但是,插入你的建议后,该程序仍然没有运行完成。 我认为问题在于推送功能。我不认为s.strings数组正在存储字符串。 – KishB87

1

你推送功能总是插入到位串0

更改像这样:

bool push(char* str) 
{ 
    if (s.size == CAPACITY) return true; // Stack is full! 
    s.strings[s.size++] = strdup(str); 
    return false; 
} 

而且具有POP(我偷了这个由迈克尔回答,并增加了对空栈中后卫):

char* pop(void) 
{ 
    if (s.size == 0) return NULL; // Stack is empty! 
    char *str = s.strings[--s.size]; 
    s.strings[s.size] = NULL; 
    return str; 
} 
+0

这解决了程序中的一个大问题。现在,唯一的问题是流行......现在是这样,我得到分段错误......不知道为什么。 – KishB87

+0

请参阅Michaels的回答,但您还需要添加检查以查看堆栈是否为空。 –

+1

最好删除一个“strdup”,因为调用它两次会导致内存泄漏。例如,它可以从push()或push()调用中移除。此外,我用我的pop(),push()从这个答案和固定断言条件在78行 - 程序运行良好。 – Michael

相关问题