C segfault,不确定是什么';正在下降

C segfault,不确定是什么';正在下降,c,formatting,format,segmentation-fault,C,Formatting,Format,Segmentation Fault,我有下面的代码,在第68行,我得到一个格式错误。 stack.c:68:警告:格式“%e”要求类型为“float*”,但参数3的类型为“double*” 在输入按钮4上,它得到一个segfault。不确定他们是否有关系。请帮忙 #include <stdio.h> #include <stdlib.h> #define OFFSET '0' #define DIM1 7 #define DIM2 5 #define RES_SIZE 1000 //typedef dou

我有下面的代码,在第68行,我得到一个格式错误。
stack.c:68:警告:格式“%e”要求类型为“float*”,但参数3的类型为“double*”

在输入
按钮4
上,它得到一个segfault。不确定他们是否有关系。请帮忙

#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);
    }
}
#包括
#包括
#定义偏移量“0”
#定义DIM1 7
#定义DIM2 5
#定义RES_大小1000
//typedef-double-double;
类型定义结构{
双*内容;
int-maxSize;
int top;
}斯塔克特;
void StackInit(stackT*stackP,int maxSize){
双*新内容;
新内容=(双*)malloc(sizeof(双)*maxSize);
if(newContents==NULL){
fprintf(stderr,“内存不足。\n”);
出口(1);
}
stackP->contents=newContents;
stackP->maxSize=maxSize;
stackP->top=-1;
}
无效堆栈销毁(stackT*stackP){
免费(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;}
无效堆栈推送(stackT*stackP,双元素){
如果(StackIsFull(stackP)){
fprintf(stderr,“无法推送元素:堆栈已满。\n”);
出口(1);
}
stackP->contents[++stackP->top]=元素;
}
双层堆叠POP(stackT*stackP){
if(StackIsEmpty(stackP)){
fprintf(stderr,“无法弹出元素:堆栈为空。\n”);
出口(1);
}
返回stackP->contents[stackP->top--];
}
无效StackShow(stackT*stackP){
int i;
printf(“[”);
对于(i=0;itop-1;i++){
printf(“%e”,stackP->contents[i]);
}
printf(“%e]\n”,stackP->contents[stackP->top-1]);
}
双shell(char*s1,双arg){
printf(“>”);
scanf(“%s%f%*c”、s1和arg);
返回arg;
}
int main(){
//char cmds[DIM1][DIM2]={{“推”}、{“弹出”}、{“添加”}、{“ifeq”}、{“跳转”}、{“打印”}、{“dup”};
斯塔克特酒店;
StackInit(&res,res_SIZE);
char cmd[DIM2];双参数=0;
arg=外壳(cmd,arg);
if(StringEqual(cmd,“push”)){
堆栈推送(&res,arg);
StackShow&res;
}
}

我只是快速查看了一下..stackShow()方法的最后一行似乎就是问题所在。除此之外,我认为您应该自己调试它,一个起点是运行您的程序,看看1个元素的索引是什么。

我只是快速查看了一下。.stackShow()方法中的最后一行似乎就是问题所在。除此之外,我认为您应该自己调试它,一个起点是运行您的程序,看看1个元素的索引是什么。

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


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

您还遇到了一个问题,因为您正在使用
arg
的值而不是其地址调用
shell
。在
scanf
中为
arg
提供地址,但所做的只是将一个值放入该子例程的局部变量中。你应该做一些更像:

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);
}

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


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

您还遇到了一个问题,因为您正在使用
arg
的值而不是其地址调用
shell
。在
scanf
中为
arg
提供地址,但所做的只是将一个值放入该子例程的局部变量中。你应该做一些更像:

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);
}

我只是快速查看了一下代码,我认为在按下第一个元素后,堆栈顶部指针设置为0。 现在,在StackShow()方法中,您正在从此行访问无效的内存位置:

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

这是数组内容的一个示例。

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

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

这是对数组内容的一个警告。

错误消息的意思与它所说的完全一致。不能将
double
变量与
float
格式说明符一起使用。使用“%lf”。
StackShow
中还有一个off-by-one错误,加上您忽略了堆栈可能为空的事实。我在68上将其更改为
%lf
,segfault仍然存在,
StackShow
有什么问题吗?您尝试过在调试器中运行代码吗?它会马上给你答案…一个错误一个错误,这就是问题所在。您的堆栈顶部位于stackP->top,而不是stackP->top-1。错误消息表示e