我尝试使用链接列表在C中编写队列(String Version)程序。
这是结构:
struct strqueue;
typedef struct strqueue *StrQueue;
struct node {
char *item;
struct node *next;
};
struct strqueue {
struct node *front;//first element
struct node *back;//last element in the list
int length;
};
我先创建一个新的StrQueue
StrQueue create_StrQueue(void) {
StrQueue q = malloc(sizeof (struct strqueue));
q->front = NULL;
q->back = NULL;
q->length = 0;
return q;
}
制作str的副本并将其放在队列的末尾
void push(StrQueue sq, const char *str) {
struct node *new = malloc(sizeof(struct node));
new->item = NULL;
strcpy(new->item,str);//invalid write size of 1 ?
new->next = NULL;
if (sq->length == 0) {
sq->front = new;
sq->back = new;
} else {
sq->back->next = new;
sq->back = new;
}
sq->length++;
}
释放sq前面的节点并返回队列中第一个字符串
char *pop(StrQueue sq) {
if (sq->length == 0) {
return NULL;
}
struct node *i = sq->front;
char *new = sq->front->item;
sq->front = i->next;
sq->length --;
free(sq->front);
return new;
}
我在strcpy(new-> item,str)的写入大小为1时无效;我不明白为什么我得到这个错误。 任何人都可以告诉我为什么,并告诉我应该如何解决它?提前谢谢。
答案 0 :(得分:5)
好的,首先,在下面的答案中我没有修复你的双链表概念,我只是告诉你如何在你的问题范围内修改上面的代码。您可能想要了解双链表的完成方式。
在:
void push(StrQueue sq, const char *str) {
struct node *new = malloc(sizeof(struct node));
new->item = NULL;
下一个陈述是错误的:
strcpy(new->item,str);
有两种方法可以解决它:
让列表管理字符串分配(以及可能的释放)。
const char *str
保证在StrQueue的有效期内有效(这正是您正在寻找的)应该是:
new->item = str;
这里我们假设str是在别处分配的动态字符串
现在,在pop中弹出字符串时你没问题。因为你要返回的指针仍然有效(你在其他地方保证它)
const char *str
不保证在StrQueue的有效期内有效然后使用:
new->item = strdup(str);
现在,在pop中弹出字符串时,你可以
item
的内容被复制(干净)这将使您的pop功能成为以下之一:
void pop(StrQueue sq) {
if (sq->length == 0) {
return NULL;
}
struct node *node = sq->front;
sq->front = node->next;
sq->length--;
free(node->item);
free(node);
}
char *pop(StrQueue sq, char *here) {
if (sq->length == 0) {
return NULL;
}
struct node *node = sq->front;
sq->front = node->next;
sq->length--;
strcpy(here, node->item);
free(node->item);
free(node);
}
char *pop(StrQueue sq) {
char *dangling_item = NULL;
if (sq->length == 0) {
return NULL;
}
struct node *node = sq->front;
sq->front = node->next;
sq->length--;
dangling_item = node->item;
free(node);
return dangling_item;
}
答案 1 :(得分:1)
我无效write size of 1 at strcpy(new->item,str);
我不明白为什么会收到此错误。任何人都可以告诉我为什么并告诉我我应该如何修复?
<强>为什么:强>
此代码:
new->item = NULL;
strcpy(new->item,str);//invalid write size of 1 ?
您不应该将空指针传递给第一个参数,它应该是指向已分配内存的指针。您可以想象,您收到此错误消息的原因是因为strcpy的实现可能如下所示:
for (int i = 0; str2[i]; i++) str1[i] = str2[i];
在for
循环的第一次迭代中,它写入地址0
(内存的只读部分) - 这将为您提供invalid write of size 1
。但是,我不确定为什么你只得到1
的大小(我想它会是字符串的整个大小)。这可能是因为 a) str
的大小只有1
或 b),因为信号SIGSEGV
会停止程序。
如何解决:
在调用new->item
之前为strcpy
分配空格,如下所示:
new->item = malloc (strlen (str) + 1); // + 1 for null-terminating character
但你可能会包含一些错误检查,如下所示:
int len = strlen (str) + 1;
if (len){
new->item = malloc (len);
if (!new->item){
return;
}
}