为什么在访问二级指针时出现分段错误? C语言
Why am i getting segmentation fault error while accessing a second level pointer?? C language
以下代码在 运行 时生成分段错误...只是因为我尝试
使用 p_list3
(二级指针)打印其内容或为其赋值...
注意:注意每个代码块中的printf(...)
差异...
完整代码在最后
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
虽然,这都不是
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s \n", (*p_list)->word, (*p_list2)->word);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
也不是这个
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
//p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
不会产生这样的错误..这里发生了什么???
完整代码
/*
@@@@ PROGRAM NAME: knkcch17proj05.c
@@@@ FLAGS: -std=c99
@@@@ PROGRAM STATEMENT:
Write a program that sorts a series of words
entered by the user:
Enter word: foo
Enter word: bar
Enter word: baz
Enter word: quux
Enter word:
In sorted order: bar baz foo quux
Assume that each word is no more than 20 characters long. Stop reading when the
user enters an empty word (i.e., presses Enter without entering a word). Store
each word in a dynamically allocated string, using an array of pointers to keep
track of the strings, as in the remind2.c program (Section 17.2). After all
words have been read, sort the array (using any sorting technique) and then use
a loop to print the words in sorted order. Hint: Use the read_line function to
read each word, as in remind2.c.
*/
#include <stdio.h>
#include <string.h> //strcpy()
#include <stdlib.h> //malloc(), free(), NULL, EXIT_FAILURE
#include <ctype.h> //isspace()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
struct node
{
char word[10];
struct node *next;
} *list = NULL;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int read_line(char str[], int n);
//------------------------START OF MAIN()--------------------------------------
int main(void)
{
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("File: %s, C Version: %ld, Date: %s, Time: %s\n\n", __FILE__, __STDC_VERSION__, __DATE__, __TIME__);
char *str;
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(str, 10));
if(!strlen(str)) //If '\n' is detected without reading character.
break;
//Read word is stored to node.
strcpy(new_word->word, str);
new_word->next = NULL;
//Load the node to list
*p_list = new_word;
p_list = &(*p_list)->next;
}
//Print words in the order they entered
printf("\nIn Unsorted order: ");
new_word = list;
while(new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
//Sorting
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%u %u %u\n", p_list, p_list2, p_list3);
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
#if 0
if((strcmp((*p_list)->word, (*p_list2)->word)) == 1) //Start [[IF1]]
{
printf("%s %s\n", (*p_list)->word, (*p_list2)->word);
if(p_list3 != NULL)
(*p_list3)->next = *p_list2; //update previous node.
(*p_list)->next = (*p_list2)->next;
(*p_list2)->next = *p_list;
struct node *temp = *p_list;
*p_list = *p_list2;
*p_list2 = temp;
} //End [[IF1]]
#endif
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
printf("\nIn sorted order: ");
new_word = list;
while(list)
{
//print the word
printf("%s ", list->word);
//prepare to free the allocated memory
new_word = list;
list = list->next;
//free the memory.
free(new_word);
}
printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
return 0;
}
//-------------------------END OF MAIN()---------------------------------------
int read_line(char str[], int n)
{
int ch, i = 0;
//while (isspace(ch = getchar()))
//;
ch = getchar();
while (ch != '\n' && ch != EOF) {
if (i < n)
str[i++] = ch;
ch = getchar();
}
str[i] = '[=13=]';
return i;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
@Yaachaka 我会比较狭隘地回答你的问题,只是解决分段错误的原因,并且不要评论程序是否有效。
崩溃的原因是在对 read_line 的调用中,您为 str:
传递了一个未初始化的值
char *str;
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(str, 10));
if(!strlen(str)) //If '\n' is detected without reading character.
break;
//Read word is stored to node.
strcpy(new_word->word, str);
new_word->next = NULL;
这是一个问题,因为 read_line 期望第一个参数指向某个地方,它可以存储正在读取的行。鉴于您已经有一个未使用的缓冲区 (new_word->word),您可以通过将上面的代码更改为直接读入 new_node->word 来修复崩溃:
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(new_word->word, 10));
if(!strlen(new_word->word)) { //If '\n' is detected without reading character.
free(new_word);
break;
}
new_word->next = NULL;
只需要指针。
str
没有分配内存,char str[21];
可以。
read_line()
需要使用 if (i < n - 1)
来确保终止零位于数组边界内。
为简单起见,每个新单词都添加到列表的开头。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct node
{
char word[21];
struct node *next;
};
int read_line(char str[], int n);
int main(void)
{
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("File: %s, C Version: %ld, Date: %s, Time: %s\n\n", __FILE__, __STDC_VERSION__, __DATE__, __TIME__);
char str[21];
struct node *p_list = NULL;
struct node *new_word = NULL;
//Get words from user
while(1)
{
printf("Enter word: ");
//Read word
read_line ( str, 21);
if ( ! strlen ( str)) { //If '\n' is detected without reading character.
break;
}
if ( ( new_word = malloc ( sizeof *new_word)) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word is stored to node.
strcpy ( new_word->word, str);
//Load the node to beginning of list
new_word->next = p_list;
p_list = new_word;
}
//Print words in the reversed order they entered
printf("\nIn Unsorted order: ");
new_word = p_list;
while ( new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
printf("\n");
//Sorting
struct node *p_list2 = p_list;
struct node *p_list3 = p_list;
struct node *sort = p_list;
while ( sort->next != NULL) //Start [[WHILE1]]
{
p_list2 = sort->next;
while ( p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %p\n", sort->word, p_list2->word, (void *)p_list3);
p_list2 = p_list2->next;
} //End [[WHILE2]]
sort = sort->next;
p_list3 = sort;
} //End [[WHILE1]]
printf("\nIn sorted order: ");
new_word = p_list;
while( new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
new_word = p_list;
while( new_word) {
p_list = new_word;
new_word = p_list->next;
//free the memory.
free( p_list);
}
printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
return 0;
}
//-------------------------END OF MAIN()---------------------------------------
int read_line(char str[], int n)
{
int ch, i = 0;
while ( ( ch = getchar ( )) != '\n' && ch != EOF) {
if (i < n - 1) {// - 1 to provide for terminating zero
str[i++] = ch;
}
}
str[i] = '[=10=]';
return i;
}
以下代码在 运行 时生成分段错误...只是因为我尝试
使用 p_list3
(二级指针)打印其内容或为其赋值...
注意:注意每个代码块中的printf(...)
差异...
完整代码在最后
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
虽然,这都不是
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s \n", (*p_list)->word, (*p_list2)->word);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
也不是这个
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
//p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
不会产生这样的错误..这里发生了什么???
完整代码
/*
@@@@ PROGRAM NAME: knkcch17proj05.c
@@@@ FLAGS: -std=c99
@@@@ PROGRAM STATEMENT:
Write a program that sorts a series of words
entered by the user:
Enter word: foo
Enter word: bar
Enter word: baz
Enter word: quux
Enter word:
In sorted order: bar baz foo quux
Assume that each word is no more than 20 characters long. Stop reading when the
user enters an empty word (i.e., presses Enter without entering a word). Store
each word in a dynamically allocated string, using an array of pointers to keep
track of the strings, as in the remind2.c program (Section 17.2). After all
words have been read, sort the array (using any sorting technique) and then use
a loop to print the words in sorted order. Hint: Use the read_line function to
read each word, as in remind2.c.
*/
#include <stdio.h>
#include <string.h> //strcpy()
#include <stdlib.h> //malloc(), free(), NULL, EXIT_FAILURE
#include <ctype.h> //isspace()
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
struct node
{
char word[10];
struct node *next;
} *list = NULL;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int read_line(char str[], int n);
//------------------------START OF MAIN()--------------------------------------
int main(void)
{
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("File: %s, C Version: %ld, Date: %s, Time: %s\n\n", __FILE__, __STDC_VERSION__, __DATE__, __TIME__);
char *str;
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(str, 10));
if(!strlen(str)) //If '\n' is detected without reading character.
break;
//Read word is stored to node.
strcpy(new_word->word, str);
new_word->next = NULL;
//Load the node to list
*p_list = new_word;
p_list = &(*p_list)->next;
}
//Print words in the order they entered
printf("\nIn Unsorted order: ");
new_word = list;
while(new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
//Sorting
struct node **p_list2 = NULL, **p_list3 = NULL;
p_list = &list;
while((*p_list)->next != NULL) //Start [[WHILE1]]
{
p_list2 = &(*p_list)->next;
while(*p_list2 != NULL) //start [[WHILE2]]
{
printf("%u %u %u\n", p_list, p_list2, p_list3);
printf("%s %s %u\n", (*p_list)->word, (*p_list2)->word, p_list3);
#if 0
if((strcmp((*p_list)->word, (*p_list2)->word)) == 1) //Start [[IF1]]
{
printf("%s %s\n", (*p_list)->word, (*p_list2)->word);
if(p_list3 != NULL)
(*p_list3)->next = *p_list2; //update previous node.
(*p_list)->next = (*p_list2)->next;
(*p_list2)->next = *p_list;
struct node *temp = *p_list;
*p_list = *p_list2;
*p_list2 = temp;
} //End [[IF1]]
#endif
p_list2 = &(*p_list2)->next;
} //End [[WHILE2]]
p_list3 = p_list;
p_list = &(*p_list)->next;
} //End [[WHILE1]]
printf("\nIn sorted order: ");
new_word = list;
while(list)
{
//print the word
printf("%s ", list->word);
//prepare to free the allocated memory
new_word = list;
list = list->next;
//free the memory.
free(new_word);
}
printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
return 0;
}
//-------------------------END OF MAIN()---------------------------------------
int read_line(char str[], int n)
{
int ch, i = 0;
//while (isspace(ch = getchar()))
//;
ch = getchar();
while (ch != '\n' && ch != EOF) {
if (i < n)
str[i++] = ch;
ch = getchar();
}
str[i] = '[=13=]';
return i;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
@Yaachaka 我会比较狭隘地回答你的问题,只是解决分段错误的原因,并且不要评论程序是否有效。
崩溃的原因是在对 read_line 的调用中,您为 str:
传递了一个未初始化的值char *str;
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(str, 10));
if(!strlen(str)) //If '\n' is detected without reading character.
break;
//Read word is stored to node.
strcpy(new_word->word, str);
new_word->next = NULL;
这是一个问题,因为 read_line 期望第一个参数指向某个地方,它可以存储正在读取的行。鉴于您已经有一个未使用的缓冲区 (new_word->word),您可以通过将上面的代码更改为直接读入 new_node->word 来修复崩溃:
struct node **p_list = &list, *new_word;
//Get words from user
while(1)
{
printf("Enter word: ");
//Allocate memory of size about struct node + 10 bytes
if((new_word = (struct node *)malloc(sizeof(struct node))) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word
(read_line(new_word->word, 10));
if(!strlen(new_word->word)) { //If '\n' is detected without reading character.
free(new_word);
break;
}
new_word->next = NULL;
只需要指针。
str
没有分配内存,char str[21];
可以。
read_line()
需要使用 if (i < n - 1)
来确保终止零位于数组边界内。
为简单起见,每个新单词都添加到列表的开头。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct node
{
char word[21];
struct node *next;
};
int read_line(char str[], int n);
int main(void)
{
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("File: %s, C Version: %ld, Date: %s, Time: %s\n\n", __FILE__, __STDC_VERSION__, __DATE__, __TIME__);
char str[21];
struct node *p_list = NULL;
struct node *new_word = NULL;
//Get words from user
while(1)
{
printf("Enter word: ");
//Read word
read_line ( str, 21);
if ( ! strlen ( str)) { //If '\n' is detected without reading character.
break;
}
if ( ( new_word = malloc ( sizeof *new_word)) == NULL)
{
printf("Error: malloc failed.");
exit(EXIT_FAILURE);
}
//Read word is stored to node.
strcpy ( new_word->word, str);
//Load the node to beginning of list
new_word->next = p_list;
p_list = new_word;
}
//Print words in the reversed order they entered
printf("\nIn Unsorted order: ");
new_word = p_list;
while ( new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
printf("\n");
//Sorting
struct node *p_list2 = p_list;
struct node *p_list3 = p_list;
struct node *sort = p_list;
while ( sort->next != NULL) //Start [[WHILE1]]
{
p_list2 = sort->next;
while ( p_list2 != NULL) //start [[WHILE2]]
{
printf("%s %s %p\n", sort->word, p_list2->word, (void *)p_list3);
p_list2 = p_list2->next;
} //End [[WHILE2]]
sort = sort->next;
p_list3 = sort;
} //End [[WHILE1]]
printf("\nIn sorted order: ");
new_word = p_list;
while( new_word)
{
printf("%s ", new_word->word);
new_word = new_word->next;
}
new_word = p_list;
while( new_word) {
p_list = new_word;
new_word = p_list->next;
//free the memory.
free( p_list);
}
printf("\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
return 0;
}
//-------------------------END OF MAIN()---------------------------------------
int read_line(char str[], int n)
{
int ch, i = 0;
while ( ( ch = getchar ( )) != '\n' && ch != EOF) {
if (i < n - 1) {// - 1 to provide for terminating zero
str[i++] = ch;
}
}
str[i] = '[=10=]';
return i;
}