这是我第一次创建堆栈。我很清楚我必须做什么,但是由于代码无法正常工作而感到沮丧。
运行正常,直到我尝试从根目录检索任何数据,这立即导致段错误。
这是我的程序:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stackNode
{
char letter;
struct stackNode * next;
};
int size=0;
int capacity=10;
struct stackNode * root=NULL;
void push(char data, struct stackNode * root)
{
if(size==capacity)
{
printf("Error: Stack Overflow\n");
return;
}
struct stackNode * new=(struct stackNode *)malloc(sizeof(struct stackNode *));
new->letter=data;
new->next=root;
printf("%c,%u", new->letter, new->next);
root=new;
printf("%c,%u", new->letter, new->next);
size++;
}
char pop(struct stackNode ** root)
{
if(size==0)
{
printf("Error: Stack is Empty\n");
return '\0';
}
printf("\npop*\n");
char temp;
printf("\n*\n");
struct stackNode * tempad;
printf("\n*\n");
temp=(*root)->letter;
printf("\n*\n");
tempad=*root;
printf("\n*\n");
*root=(*root)->next;
printf("\n*\n");
free(tempad);
printf("\n*\n");
size--;
return temp;
}
int main()
{
push('c', root);
push('v', root);
push('n', root);
printf("%c %c %c", pop(&root), pop(&root), pop(&root));
}
以下是输出:
pop*
*
*
Segmentation fault
有人可以指出错误吗?
答案 0 :(得分:1)
这确实是令人困惑的代码(即,与局部作用域中的变量同名的全局变量)。我只是要重写它,未经测试并且可以在移动设备上使用,但应该没问题。您可以进行比较以查看问题。一方面,尽管您将局部变量root设置为最新的分配,而不是全局根。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct stackNode
{
char letter;
struct stackNode* prev;
};
stackNode* kTailStack = NULL;
void push(char data)
{
stackNode* p=(stackNode *)malloc(sizeof(stackNode));
p->letter=data;
p->prev=kTailStack;
kTailStack = p;
}
char pop()
{
stackNode* prev_tail = kTailStack;
char n = 0;
if (prev_tail != NULL)
{
n = prev_tail->letter;
kTailStack = prev_tail->prev;
free(prev_tail);
}
return n;
}
int main()
{
push('c', kTailStack);
push('v', kTailStack);
push('n', kTailStack);
printf("%c %c %c", pop(kTailStack), pop(kTailStack), pop(kTailStack));
}
答案 1 :(得分:1)
主要问题是使用不必要的全局变量,这似乎引起混乱。在using System;
using CoreAnimation;
using CoreGraphics;
using YourNameSpace;
using YourNameSpace.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(GradientView), typeof(GradientViewRenderer))]
namespace YourNameSpace.iOS
{
public class GradientViewRenderer : BoxRenderer
{
public override void Draw(CGRect rect)
{
//base.Draw(rect);
GradientView formsGradientView = Element as GradientView;
var currentContext = UIGraphics.GetCurrentContext();
currentContext.SaveState();
var colorSpace = CGColorSpace.CreateDeviceRGB();
var startColor = formsGradientView.StartColor;
var startColorComponents = startColor.ToCGColor().Components;
var middleColor = formsGradientView.MiddleColor;
var middleColorComponents = middleColor.ToCGColor().Components;
var endColor = formsGradientView.EndColor;
var endColorComponents = endColor.ToCGColor().Components;
nfloat[] colorComponents = {
startColorComponents[0], startColorComponents[1], startColorComponents[2], startColorComponents[3],
middleColorComponents[0], middleColorComponents[1], middleColorComponents[2], middleColorComponents[3],
endColorComponents[0], endColorComponents[1], endColorComponents[2], endColorComponents[3]
};
nfloat[] locations = { 0f, 0.5f, 1f };
var gradient = new CGGradient(colorSpace, colorComponents, locations);
var startPoint = new CGPoint(0, NativeView.Bounds.Height);
var endPoint = new CGPoint(NativeView.Bounds.Width, NativeView.Bounds.Height);
currentContext.DrawLinearGradient(gradient, startPoint, endPoint, CGGradientDrawingOptions.None);
currentContext.RestoreState();
}
}
}
中,该参数的类型为push
,但是它像引用全局struct stackNode *
一样被操纵。但是root
纯粹是本地的,对全局root = new
没有影响。但是,root
确实会影响全局范围。这破坏了堆栈的逻辑状态,并且您在size++
开头的错误处理程序认为pop
并没有抱怨。然后,该函数会忠实地取消引用size == 3
,从而使程序崩溃。
正确的堆栈类不应使用全局数据。它应该将所有必要的状态封装在结构中。这使其可重用,从而可以创建多个堆栈(这是我在使用的大多数类中想要的属性)。
其他一些建议:
root
并避免使用像stderr
这样的不可思议的值,这些值可能会误认为实际的节点数据。malloc
。这样可以抑制错误,并且视觉上很吵。return '\0';
感觉很随意。我不确定是否有这个意义(但是如果有的话,将其添加到结构中)。如果每个节点内有关堆栈的元数据太多(理想情况下应该没有),请创建一个capacity
结构以包含此元数据,并将其指向实际的Stack
链。 stackNode
/ malloc
很慢。对于字符数据,带有free
指针的简单数组将更快,更容易实现。您可以通过在top
时周期性地将数组加倍并在top >= capacity
时收缩来对分配调用进行摊销。这里有一个快速的重写方法(不建议使用top < capacity / 2
包装器结构或数组):
Stack