C段错误,不知道发生了什么事

时间:2011-08-01 06:15:56

标签: c formatting format segmentation-fault

我有以下代码,在第68行,我收到格式错误。 stack.c:68: warning: format ‘%e’ expects type ‘float *’, but argument 3 has type ‘double *’

在输入push 4上,它会出现段错误。不确定它们是否相关。请帮忙!

#include <stdio.h>
#include <stdlib.h>
#define OFFSET '0'
#define DIM1 7
#define DIM2 5
#define RES_SIZE 1000

//typedef double double;

typedef struct {
  double *contents;
  int maxSize;
  int top;
} stackT;

void StackInit(stackT *stackP, int maxSize) {
    double *newContents;
    newContents = (double *)malloc(sizeof(double)*maxSize);
    if (newContents == NULL) {
        fprintf(stderr, "Not enough memory.\n");
        exit(1);
    }

    stackP->contents = newContents;
    stackP->maxSize = maxSize;
    stackP->top = -1;
}

void StackDestroy(stackT *stackP) {
    free(stackP->contents);
    stackP->contents = NULL;
    stackP->maxSize = 0;
    stackP->top = -1;
}

int StackIsEmpty(stackT *stackP) { return stackP->top < 0; }

int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; }

void StackPush(stackT *stackP, double element) {
    if(StackIsFull(stackP)) {
        fprintf(stderr, "Can't push element: stack is full.\n");
        exit(1);
    }
    stackP->contents[++stackP->top] = element;
}

double StackPop(stackT *stackP) {
    if(StackIsEmpty(stackP)) {
        fprintf(stderr, "Can't pop element: stack is empty.\n");
        exit(1);
    }
    return stackP->contents[stackP->top--];
}

void StackShow(stackT *stackP) {
    int i;
    printf("[ ");
    for (i = 0; i < stackP->top - 1; i++) {
        printf("%e, ", stackP->contents[i]);
    }
    printf("%e ]\n", stackP->contents[stackP->top - 1]);
}

double shell(char* s1, double arg) {
    printf(">   ");
    scanf("%s %f%*c", s1, &arg);
    return arg;
}

int main() {
    //char cmds[DIM1][DIM2] = {{"push"}, {"pop"}, {"add"}, {"ifeq"}, {"jump"}, {"print"}, {"dup"}};
    stackT res;
    StackInit(&res, RES_SIZE);
    char cmd[DIM2]; double arg = 0;
    arg = shell(cmd, arg);
    if (StringEqual(cmd, "push")) {
        StackPush(&res, arg);
        StackShow(&res);
    }
}

3 个答案:

答案 0 :(得分:2)

快速查看代码,我认为在推送第一个元素后,堆栈顶部指针设置为0。 现在你在StackShow()方法中从这一行访问一个无效的内存位置:

 printf("%e ]\n", stackP->contents[stackP->top - 1]); // accessing invalid location stackP->contents[-1] 

这是数组内容的off-by-one error

答案 1 :(得分:1)

我刚看了一下..你的stackShow()方法的最后一行似乎是个问题。除了我认为你应该自己调试,一个起点是贯穿你的程序,看看1个元素的索引是什么。

答案 2 :(得分:1)

编辑:kakira和CodeBuzz是正确的。您的段错误来自StackShow。我在下面指出的错误会导致arg设置不正确,但不会导致您的段错误。


您的编译器正在告诉您问题所在。你的scanf期待一个浮点数的指针,但是你指的是一个双精度指针。在Linux上,您可以将scanf的double指定为%lf,但如果您的编译器需要%e,那么请尝试使用它。

您也遇到了问题,因为您拨打的shell的值为arg而不是其地址。您将地址提供给arg中的scanf,但您所做的只是将值放入该子例程的本地变量中。你应该做更多的事情:

void shell(char *s1, double *arg)
{
    scanf("%s %lf%*c", s1, arg);
}

main()
{
    ...
    double arg;
    shell(cmd, &arg);
}

这样,scanf会填充您传递的arg,而您也不需要返回该值。如果您希望单独继续返回值,则不要将其传入,因为它只会混淆问题。 E.g:

double shell(char *s1, double *arg)
{
    double arg;
    scanf("%s %lf%*c", s1, &arg);
    return arg;
}

main()
{
    ...
    double arg;
    arg = shell(cmd);
}