С Сегфо, не уверен, что происходит вниз - PullRequest
0 голосов
/ 01 августа 2011

У меня есть следующий код, и в строке 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 ]

2 голосов
/ 01 августа 2011

Только что быстро просмотрел ваш код, я думаю, что после нажатия первого элемента ваш указатель вершины стека устанавливается в 0.Теперь в вашем методе StackShow () вы получаете доступ к неверной ячейке памяти из этой строки:

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

Это ошибка off-by-one для содержимого массива.

1 голос
/ 01 августа 2011

РЕДАКТИРОВАТЬ : Какира и CodeBuzz верны.Ваш segfault от StackShow.Ошибка, которую я указал ниже, приведет к неправильной установке arg, но это не приведет к вашей ошибке.


Ваш компилятор сообщает вам, в чем проблема.Ваш scanf ожидает указатель на число с плавающей запятой, но вы даете указатель на двойное число.В Linux вы должны указать double to scanf как %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, который вы передаете, и вам не нужно также возвращать значение.Если вы хотите продолжить возвращать значение отдельно, не передавайте его, так как это только запутывает проблему.Например:

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

main()
{
    ...
    double arg;
    arg = shell(cmd);
}
1 голос
/ 01 августа 2011

Я только что бросил быстрый взгляд ... проблема в последней строке вашего метода stackShow (). Кроме того, я думаю, что вы должны отладить это самостоятельно, отправной точкой было бы просмотреть вашу программу и посмотреть, какие будут индексы для 1 элемента.

...