C segfault,不确定是什么';正在下降
我有下面的代码,在第68行,我得到一个格式错误。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
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