2013-02-24 57 views
1

文件stack.h实现在C堆栈与一般的风格

typedef struct 
{ 
    void *elems; 
    int elem_size; 
    int log_len; 
    int alloc_len; 
    void (*free_fn)(void *); 
} stack; 

void stack_new(stack *s, int elem_size, void (*free_fn)(void *)); 
void stack_dispose(stack *s); 
void stack_push(stack *s, void *value); 
void stack_pop(stack *s, void *address); 

和实现文件stack.c

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#define assert(condition) if(!condition) printf("assert fail\n");exit(0) 

void strfree(void *elem); 

int main() 
{ 
    stack s; 
    int i; 
    char *copy, *top; 
    const char *friends[] = {"joe", "castiel", "lily"}; 
    stack_new(&s, sizeof(char *), strfree); 
    for(i=0; i<3; i++) 
    { 
     copy = strdup(friends[i]); 
     stack_push(&s, &cp); 
    } 

    for(i=0; i<=3; i++) 
    { 
     stack_pop(&s, &top); 
     printf("%s\n", top); 
    } 
    stack_dispose(&s); 
    return 1; 
} 

void strfree(void *elem) 
{ 
    free(*(char **)elem); 
} 

void stack_new(stack *s, int elem_size, void (*free_fn)(void *)) 
{ 
    assert(elem_size > 0); 
    s->alloc_len = 4; 
    s->free_fn = free_fn; 
    s->log_len = 0; 
    s->elem_size = elem_size; 
    s->elems = malloc(s->alloc_len * s->elem_size); 
    assert(s->elems != NULL); 
} 

void stack_dispose(stack *s) 
{ 
    int i; 
    if(s->free_fn) 
    { 
     for(i=0; i<s->log_len; i++) 
     { 
      s->free_fn((char *)s->elems + i * s->elem_size); 
     } 
    } 
    free(s->elems); 
} 

void stack_push(stack *s, void *v) 
{ 
    if(s->log_len == s->alloc_len) 
    { 
     s->alloc_len *= 2; 
     s->elems = realloc(s->elems, s->alloc_len*s->elem_size); 
     assert(s->elems != NULL); 
    } 
    memcpy((char *)s->elems+s->log_len*s->elem_size, v, s->elem_size); 
    s->log_len++; 
} 

void stack_pop(stack *s, void *address) 
{ 
    assert(s->log_len > 0); 
    void *source = (char *)s->elems + (s->log_len - 1) * s->elem_size; 
    memcpy(address, source, s->elem_size); 
    s->log_len--; 
} 

所以它编译,但它不运行。

  1. 它有一个关于指针和整数之间的比较警告这是从代码

    assert(s->elems != NULL); 
    
  2. 这是什么地方坏了,也不会打印出此定义

    const char *friends[] = {"joe", "castiel", "lily"}; 
    
  3. 三个名字

我知道代码太多了,但我真的希望得到一些帮助,我在我的智慧在这里结束。

回答

5

的一个问题是你的assert宏:

#define assert(condition) if(!condition) printf("assert fail\n");exit(0) 

exit(0);不管条件是否为真或假的(再次查看生成的代码)被执行。如果你想断言,使用标准#include <assert.h>

你的第一标识的问题是与:

assert(s->elems != NULL); 

给出的定义,这相当于:

if (!s->elems != NULL) 
    printf("assert fail\n"); 
exit(0); 

!s->elems是整数,0或1,用一个空指针相比不变。因此警告。编写宏时,将参数括在括号中。在最低限度:

#define assert(condition) if(!(condition)){printf("assert fail\n");exit(1);} 

这仍然不是一个良好的宏观,但至少这将摆脱第一编译错误的,你的stack_new()不会退出时,它被称为只是因为它被调用。请注意,当出现问题时,通常以非零状态退出 - 退出时表示成功。

+1

+1使用标准 2013-02-24 04:53:40

1

使用GDB在调试器中运行您的代码,查看它正在逐行执行的操作。谷歌“gdb备忘单”开始使用-g编译你的代码。

+0

谢谢你,因为我没有使用IDE,我忘了我可以调试我的代码 – castiel 2013-02-24 04:53:43