C-带结构的分段错误
如果这是一个容易解决的问题,我真的很抱歉,但我是一个初学者。 我有一个任务将一些函数写入堆栈结构。给出了结构。我无法消除push()行的->元素中的分段错误 我不知道在几个小时的谷歌搜索之后,到底出了什么问题 代码如下:C-带结构的分段错误,c,struct,segmentation-fault,stack,C,Struct,Segmentation Fault,Stack,如果这是一个容易解决的问题,我真的很抱歉,但我是一个初学者。 我有一个任务将一些函数写入堆栈结构。给出了结构。我无法消除push()行的->元素中的分段错误 我不知道在几个小时的谷歌搜索之后,到底出了什么问题 代码如下: #define STACK_SIZE 5 #include <stdio.h> #include <stdlib.h> typedef struct stackADT { int elements[STACK_SIZE]; int c
#define STACK_SIZE 5
#include <stdio.h>
#include <stdlib.h>
typedef struct stackADT {
int elements[STACK_SIZE];
int count;
} stack;
void initialize(stack *s)
{
stack *newStack;
newStack = malloc(sizeof(*newStack));
newStack->count = 0;
s = newStack;
}
int push(stack *s, int value)
{
if(s->count == 5) return -1;
else {
s->elements[s->count++] = value;
return s->elements[s->count-1];
}
}
int main()
{
stack* sA;
stack* sB;
initialize(sA);
initialize(sB);
printf("%d\n",push(sA,3));
return 0;
}
#定义堆栈大小5
#包括
#包括
类型定义结构stackADT{
int元素[堆栈大小];
整数计数;
}堆叠;
无效初始化(堆栈*s)
{
堆栈*新闻标题;
newStack=malloc(sizeof(*newStack));
新闻标题->计数=0;
s=新闻标题;
}
int push(堆栈*s,int值)
{
如果(s->count==5)返回-1;
否则{
s->elements[s->count++]=值;
返回s->elements[s->count-1];
}
}
int main()
{
堆栈*sA;
stack*sB;
初始化(sA);
(某人);
printf(“%d\n”,push(sA,3));
返回0;
}
因为您是按值传递两个指针(因此实际上是传递指针的副本),所以将initialize函数更改为int initilize(stack**s)
和s=newStack代码>至*s=newStack代码>然后像这样调用initializeinitialize(&sA);初始化(&sB)代码>
你真的不应该动态分配对象,除非你必须这样做,而且你没有空闲()
占用你分配的内存,这是内存泄漏。当你将指针传递给函数时,函数会收到指针的副本。这通常很好,除非您正在更改/创建指针的起始地址
在您的情况下,sA
和sB
不包含地址(当您将它们传递到initialize
时,它们是指向空的指针)。因此,您的initialize
函数必须采用指针的地址,而不是指针本身,以便为指针分配一个在main
中可见的地址。例如:
void initialize(stack **s)
{
stack *newStack;
newStack = malloc(sizeof(*newStack));
newStack->count = 0;
*s = newStack;
}
...
initialize (&sA);
取消引用上面的双指针**s
(例如*s=newStack;
),将newStack
的地址指定为指针s
的值
我还建议在将newStack
的位置分配给*s
之前检查分配是否成功:
void initialize(stack **s)
{
stack *newStack;
if (!(newStack = malloc(sizeof(*newStack)))) {
fprintf (stderr, "%s() error: memory allocation failed.\n", __func__);
exit (EXIT_FAILURE);
}
newStack->count = 0;
*s = newStack;
}
我想你需要像下面这样的东西
#include <stdio.h>
#define STACK_SIZE 5
typedef struct stackADT
{
int elements[STACK_SIZE];
int count;
} stack;
void initialize( stack *s )
{
s->count = 0;
}
int push( stack *s, int value )
{
return s->count == STACK_SIZE ? -1 : ( s->elements[s->count++] = value );
}
int main(void)
{
stack sA;
stack sB;
initialize( &sA );
initialize( &sB );
printf( "%d\n", push( &sA, 3 ) );
return 0;
}
#包括
#定义堆栈大小5
类型定义结构stackADT
{
int元素[堆栈大小];
整数计数;
}堆叠;
无效初始化(堆栈*s)
{
s->count=0;
}
int push(堆栈*s,int值)
{
返回s->count==堆栈大小?-1:(s->elements[s->count++]=value);
}
内部主(空)
{
堆栈sA;
堆叠某人;
初始化(&sA);
初始化(&sB);
printf(“%d\n”,推送(&sA,3));
返回0;
}
您收到分段错误,因为您试图在push()
中为未分配的内存区域分配一个值initialize()
可以成功地分配内存并使用count=0
对其进行初始化,但是s=newStack
的分配不起作用。正如David和Alejandro所指出的,您传递的是“指针的副本”。本质上,您传递的是未初始化的堆栈
变量的地址,但您并没有传递函数一种用新地址更新该变量的方法。您需要向它传递一个指向堆栈指针的指针。(也称为二级指针。)这意味着initialize()
将接收保存堆栈结构内存地址的变量的内存地址。因此,该函数可以将二级指针的指针对象的地址分配给malloced堆栈
也许只要看一下代码就更容易理解:
#define STACK_SIZE 5
#include <stdio.h>
#include <stdlib.h>
typedef struct stackADT {
int elements[STACK_SIZE];
int count;
} stack;
void initialize(stack **s)
{
stack *newStack;
newStack = malloc(sizeof(*newStack));
if(NULL == newStack){
// Malloc could not allocate memory
// for newStack.
// Set s to NULL to indicate the error
s = NULL;
// Return prematurely
return;
} // else, malloc succeeded
newStack->count = 0;
// Assign the value of the malloced stack pointer to the pointee of stack **s
*s = newStack;
}
int push(stack *s, int value)
{
if( s->count == STACK_SIZE ){
// Stack has too many elements.
// Return with error value (-1)
return -1;
} else {
// Assign the new value to the current last index
s->elements[s->count] = value;
// Add count to indicate a new variable has been added
s->count++;
// Use the array to return the value just added
return s->elements[ (s->count - 1) ];
}
}
int main()
{
stack* sA;
stack* sB;
// Send the function a pointer to the stack pointer
initialize(&sA);
initialize(&sB);
if(sA == NULL){
puts("Could not allocate the memory for stack variable sA.\n");
return -1;
}
printf("%d\n", push(sA, 3) );
// Clean up the memory
free(sA);
free(sB);
return 0;
}
#定义堆栈大小5
#包括
#包括
类型定义结构stackADT{
int元素[堆栈大小];
整数计数;
}堆叠;
无效初始化(堆栈**s)
{
堆栈*新闻标题;
newStack=malloc(sizeof(*newStack));
if(NULL==newStack){
//Malloc无法分配内存
//用于新闻标题。
//将s设置为NULL以指示错误
s=零;
//过早返回
返回;
}//否则,malloc成功了
新闻标题->计数=0;
//将malloced堆栈指针的值分配给堆栈**s的指针对象
*s=新闻标题;
}
int push(堆栈*s,int值)
{
如果(s->count==堆栈大小){
//堆栈中的元素太多。
//返回错误值(-1)
返回-1;
}否则{
//将新值指定给当前的最后一个索引
s->elements[s->count]=值;
//添加计数以指示已添加新变量
s->count++;
//使用数组返回刚刚添加的值
返回s->elements[(s->count-1)];
}
}
int main()
{
堆栈*sA;
stack*sB;
//向函数发送指向堆栈指针的指针
初始化(&sA);
初始化(&sB);
if(sA==NULL){
puts(“无法为堆栈变量sA分配内存。\n”);
返回-1;
}
printf(“%d\n”,push(sA,3));
//清理记忆
免费(sA);
自由(某人);
返回0;
}
我还稍微修改了代码,在push()
函数中拆分了value
的赋值,并添加了malloc()
错误检查
注意:如果您对它感到满意,我建议您使用Vlad的推送功能。它更短更简洁;然而,它牺牲了可读性。由于您是初学者,我决定将其展开可能更容易理解。@Mirko Richter为什么要动态分配stack类型的对象?您可以简单地定义一个堆栈,如stacksa;函数初始化也不初始化任何内容。:)OK。如何将函数initialize更改为初始化某些内容?;)谢谢,这个有用!我得到的部分是指针的副本。在里面