释放Struct-C中的字符串时出现分段错误
我被一个分割错误困扰了很长时间。我声明了一个带字符串指针的结构。我编写了两个函数,create和remove来操作值。结构如下所示:释放Struct-C中的字符串时出现分段错误,c,malloc,C,Malloc,我被一个分割错误困扰了很长时间。我声明了一个带字符串指针的结构。我编写了两个函数,create和remove来操作值。结构如下所示: #include "filename.h" //*in filename.h:* typedef struct linkNode linkNode_t; struct linkNode{ struct linkNode *next; char *value; }; linkNode_t* removebyValue(linkNode_t*
#include "filename.h"
//*in filename.h:* typedef struct linkNode linkNode_t;
struct linkNode{
struct linkNode *next;
char *value;
};
linkNode_t* removebyValue(linkNode_t* start, char* valu){
/**removes the first instance of a node with a certain value. Return *start after removing.
if linked list becomes empty, return NULL*/
linkNode_t *current=start;
linkNode_t *previous=start;
while(current!=NULL){
if(strcmp(valu,current->value)==0) {//found the node to delete
if(current==start){//removing the head
linkNode_t* retvalue= current->next;
free(current->value);
free(current);
return retvalue;
}
else{ //removing other elements in the linked list
previous->next=current->next;
free(current->value);
free(current);
return start;
}
}
else{
previous=current;
current=current->next;
}
}
return start;
}
创建函数将首先为节点分配内存,然后为值分配内存,然后将输入值复制到值字段:
linkNode_t* create(char* stuff){
linkNode_t *ptr=malloc(sizeof(linkNode_t));
if(ptr==NULL){
printf("malloc failure");
return NULL;
}
char* tempvalu=malloc(sizeof(char)*strlen(stuff)+1);
if(tempvalu==NULL){
printf("malloc failure");
return NULL;
}
strcpy(tempvalu,stuff);
ptr->next=NULL;
ptr->value=tempvalu;
return ptr;
}
函数用于将节点插入到链接列表中:
linkNode_t* insertLast(linkNode_t* start, linkNode_t* newNode){
linkNode_t* current=start;
while(current->next!=NULL){
current=current->next;
}
//now current points to the last element in the linked list
current->next=newNode;
return start;
}
导致我出现问题的部分如下所示:
#include "filename.h"
//*in filename.h:* typedef struct linkNode linkNode_t;
struct linkNode{
struct linkNode *next;
char *value;
};
linkNode_t* removebyValue(linkNode_t* start, char* valu){
/**removes the first instance of a node with a certain value. Return *start after removing.
if linked list becomes empty, return NULL*/
linkNode_t *current=start;
linkNode_t *previous=start;
while(current!=NULL){
if(strcmp(valu,current->value)==0) {//found the node to delete
if(current==start){//removing the head
linkNode_t* retvalue= current->next;
free(current->value);
free(current);
return retvalue;
}
else{ //removing other elements in the linked list
previous->next=current->next;
free(current->value);
free(current);
return start;
}
}
else{
previous=current;
current=current->next;
}
}
return start;
}
大体上,我创建了一个包含两个元素(1和2)的链表,并在出现分段错误时尝试释放元素1
int main(){
linkNode_t *pt1=create("1");
pt1=insertLast(pt1,create("2"));
removebyValue(pt1,"1"); //Causes seg fault. If I replace "1" by "2" nothing happens
有人能给点建议吗?提前谢谢
编辑:我放了所有可能相关的代码,因为有人说我放的部分没有错误我认为您在正确维护开始指针的同时,考虑了删除节点的问题。考虑一种希望更简单的方法。
typedef struct node_t
{
struct node_t* next;
char* value;
} node_t;
node_t* remove(node_t *start, const char* valu)
{
node_t* current=start;
node_t* prev=NULL;
while(current && strcmp(current->value, valu))
{
prev = current;
current = current->next;
}
if (current)
{
if (prev) // we're not deleting start node
prev->next = current->next;
else // we *are* deleting start node
start = current->next;
// now the node is unlinked. remove it.
free(current->value);
free(current);
}
return start;
}
我认为您在正确维护开始指针的同时,考虑了删除节点的问题。考虑一种希望更简单的方法。
typedef struct node_t
{
struct node_t* next;
char* value;
} node_t;
node_t* remove(node_t *start, const char* valu)
{
node_t* current=start;
node_t* prev=NULL;
while(current && strcmp(current->value, valu))
{
prev = current;
current = current->next;
}
if (current)
{
if (prev) // we're not deleting start node
prev->next = current->next;
else // we *are* deleting start node
start = current->next;
// now the node is unlinked. remove it.
free(current->value);
free(current);
}
return start;
}
这里有一个替代的测试代码,可以很好地工作,看看它是否有用。 此外,您还可以添加
typedef struct node_t {
struct node_t* next;
char* value;
} node;
这可能看起来更容易理解,但这并不是因为typedef的本质令人困惑。
我强烈建议你看看
这是linux内核的编码风格,它非常简短和简单,不是特别的一个规律,但值得注意
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node_t {
struct node_t* next;
char* value;
};
struct node_t* create(const char* istr)
{
struct node_t* ptr = (struct node_t*)malloc(sizeof(struct node_t));
char* tmp = (char*)malloc(sizeof(char) * (strlen(istr) + 1));
strcpy(tmp, istr);
ptr->next = 0;
ptr->value = tmp;
return ptr;
}
struct node_t* remove(struct node_t* start, const char* value)
{
struct node_t* current = start;
struct node_t* prev = start;
while (current != 0) {
if (!strcmp(value, current->value)) {
if (current == start) {
struct node_t* retval = current->next;
free(current->value);
free(current);
return retval;
} else {
/* nothing happens */
return 0;
}
}
}
}
int main(const int argc, const char** argv)
{
struct node_t* pt = create("1");
printf("%s\n", pt->value);
pt->next = create("2");
printf("%s\n", pt->next->value);
remove(pt, "1");
return 0;
}
#包括
#包括
#包括
结构节点{
结构节点*next;
字符*值;
};
结构节点创建(常量字符*istr)
{
结构节点ptr=(结构节点)malloc(sizeof(结构节点));
char*tmp=(char*)malloc(sizeof(char)*(strlen(istr)+1));
strpy(tmp,istr);
ptr->next=0;
ptr->value=tmp;
返回ptr;
}
结构节点删除(结构节点开始,常量字符*值)
{
结构节点\u t*当前=开始;
结构节点\u t*prev=开始;
while(当前!=0){
如果(!strcmp(值,当前->值)){
如果(当前==开始){
结构节点\u t*retval=当前->下一步;
自由(当前->值);
自由(电流);
返回返回;
}否则{
/*什么也没发生*/
返回0;
}
}
}
}
int main(常量int argc,常量字符**argv)
{
结构节点_t*pt=create(“1”);
printf(“%s\n”,pt->value);
pt->next=创建(“2”);
printf(“%s\n”,pt->next->value);
移除(pt,“1”);
返回0;
}
这里有一个替代的测试代码,可以很好地工作,试一下,看看它是否有用。
此外,您还可以添加
typedef struct node_t {
struct node_t* next;
char* value;
} node;
这可能看起来更容易理解,但这并不是因为typedef的本质令人困惑。
我强烈建议你看看
这是linux内核的编码风格,它非常简短和简单,不是特别的一个规律,但值得注意
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node_t {
struct node_t* next;
char* value;
};
struct node_t* create(const char* istr)
{
struct node_t* ptr = (struct node_t*)malloc(sizeof(struct node_t));
char* tmp = (char*)malloc(sizeof(char) * (strlen(istr) + 1));
strcpy(tmp, istr);
ptr->next = 0;
ptr->value = tmp;
return ptr;
}
struct node_t* remove(struct node_t* start, const char* value)
{
struct node_t* current = start;
struct node_t* prev = start;
while (current != 0) {
if (!strcmp(value, current->value)) {
if (current == start) {
struct node_t* retval = current->next;
free(current->value);
free(current);
return retval;
} else {
/* nothing happens */
return 0;
}
}
}
}
int main(const int argc, const char** argv)
{
struct node_t* pt = create("1");
printf("%s\n", pt->value);
pt->next = create("2");
printf("%s\n", pt->next->value);
remove(pt, "1");
return 0;
}
#包括
#包括
#包括
结构节点{
结构节点*next;
字符*值;
};
结构节点创建(常量字符*istr)
{
结构节点ptr=(结构节点)malloc(sizeof(结构节点));
char*tmp=(char*)malloc(sizeof(char)*(strlen(istr)+1));
strpy(tmp,istr);
ptr->next=0;
ptr->value=tmp;
返回ptr;
}
结构节点删除(结构节点开始,常量字符*值)
{
结构节点\u t*当前=开始;
结构节点\u t*prev=开始;
while(当前!=0){
如果(!strcmp(值,当前->值)){
如果(当前==开始){
结构节点\u t*retval=当前->下一步;
自由(当前->值);
自由(电流);
返回返回;
}否则{
/*什么也没发生*/
返回0;
}
}
}
}
int main(常量int argc,常量字符**argv)
{
结构节点_t*pt=create(“1”);
printf(“%s\n”,pt->value);
pt->next=创建(“2”);
printf(“%s\n”,pt->next->value);
移除(pt,“1”);
返回0;
}
旁注,strlen(stuff)+1
@slugonamission:只有在(sizeof(char)!=1)
的情况下,才会有括号。我刚刚把你的部分放在一个编译程序中,它不会崩溃,所以我怀疑你已经删除了导致它崩溃的位……在我发布任何东西之前,我试图理解这个remove()
函数的返回值应该是什么。它是否始终应该是指向已删除节点后面的节点(如果有)的指针?当不按地址传递头指针以进行可能的修改时,通常会返回活动头指针,从而允许您写入pt=remove(pt,“1”)代码>。但如果删除的节点不是列表中的前一个节点,则无法执行此操作。所以我有点不知所措了。@WhozCraig remove函数应该将head指针作为输入,并将head(新head)指针作为输出返回。我刚刚把我的代码更新到了完整的版本,希望对你有所帮助。谢谢旁注,strlen(stuff)+1
@slugonamission:只有在(sizeof(char)!=1)
的情况下,才应该有括号。我刚刚把你的部分放在一个编译程序中,它不会崩溃,所以我怀疑你已经删除了导致它崩溃的位……在我发布任何东西之前,我试图理解这个remove()
函数的返回值应该是什么。它是否始终应该是指向已删除节点后面的节点(如果有)的指针?当不按地址传递头指针以进行可能的修改时,通常会返回活动头指针,从而允许您写入pt=remove(pt,“1”)代码>。但如果删除的节点不是列表中的前一个节点,则无法执行此操作。所以我有点不知所措了。@WhozCraig remove函数应该将head指针作为输入,并返回head(新head)p