我是C的新手并且不知所措。我一直在墙上撞了几个小时。
我创建了两个struct
来保存我的链表节点。第一个,struct movie
显然拥有电影。第二个struct actor
是将actor节点添加到电影节点。
struct movie {
struct movie* next;
struct actor* actors;
char name[100];
int rating;
genre type;
} *list = NULL;
// contains actor information
struct actor {
struct actor* next;
char name[100];
};
当我尝试将actor
添加到movie
时会出现问题。
int add_actor(char* movie_name, char* actor_name)
{
struct movie *tmp = list, *tmpList = NULL;
struct actor *tmpActor = NULL, *current = NULL;
//check if movie name exists in list
while (tmp != NULL) {
if (strcmp(tmp->name, movie_name) == 0) {
tmpList = tmp;
}
tmp = tmp->next;
} //make sure newActor->next is pointing to the correct place
if (tmpList == NULL) { return 0; } //if movie in not in list, return 0
//The problem occurs most often at this line, with the exception below.
//Exception thrown at 0x77433500 (ntdll.dll) in hw7.exe: 0xC0000005: Access violation reading location 0x006F4E42
struct actor *newActor = (struct actor*)malloc(sizeof(struct actor));//create new actor node
if (tmpList->actors == NULL){ //if the movie has no actors in list
tmpList->actors = newActor;
strcpy(newActor->name, actor_name);
newActor->next = NULL;
return 1;
}
else { //check if actor name already exists in list
while (tmpActor != NULL) {
if (strcmp(tmpActor->name, actor_name) == 0) {
return -1; //if actor already exists return -1
}
tmpActor = tmpActor->next;
}
tmpActor = tmp->actors;
//insert at beginning of list
if (strcmp(actor_name, tmpActor->name) >= 0) {
newActor->next = tmpActor;
tmpActor = newActor;
return 1;
}
//insert actor in arbitrary position
while (tmpActor != NULL && strcmp(actor_name, tmpActor->name)<0) {
current = tmpActor;
tmpActor = tmpActor->next;
}
newActor->next = current->next;
strcpy(newActor->name, actor_name);
current->next = newActor;
return 1;
}
}
充其量我能够将两个演员添加到两部不同的电影中。问题总是出现在第三个条目上。
更新:
经过仔细挑选我的代码后,我发现了一个明显的错误。传递任何大于几个字符的程序时程序会崩溃。当我声明传递给movie_name
函数的actor_name
和add_actor
指针变量时,我没有为更大的名称分配足够的空间。
char* movie_name = (char*)malloc(sizeof(char*));
char* actor_name = (char*)malloc(sizeof(char*));
更改为:
char* movie_name = (char*)malloc(5000*sizeof(char*));
char* actor_name = (char*)malloc(5000*sizeof(char*));
我可以在不崩溃的情况下添加电影和演员。
答案 0 :(得分:3)
我看到两个错误
但是,它们中的任何一个都不太可能是崩溃的根源,因为在您的测试用例中都没有执行。 (除非你在每部电影中添加两个演员 - 这个问题很难解释)。
最终的原因可能在于添加电影或其他地方的功能
当堆已经损坏时,您可以肯定地说它是在程序启动和崩溃之间的某个时刻发生的。
但我还是会提到这些错误......
一:
当你达到这一点时:
tmpActor = tmp->actors;
第一次循环保证 tmp
为NULL
你可能意味着
tmpActor = tmpList->actors;
二:
当你到达这里时:
//insert at beginning of list
if (strcmp(actor_name, tmpActor->name) >= 0) {
newActor->next = tmpActor;
tmpActor = newActor;
return 1;
}
您将新演员分配到tmpActor
,这是一个局部变量。
我认为你应该替换
tmpActor = newActor;
与
tmpList->actors = newActor;
三:不要投出malloc
的结果。
答案 1 :(得分:0)
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct movie MOVIE;
typedef struct actor ACTOR;
typedef enum {
Action,
Documentary,
Animation /*etc ...*/
}genre;
struct movie{
MOVIE* next;
ACTOR* actors;
char name[100];
int rating;
genre type;
} ;
// contains actor information
struct actor {
ACTOR* next;
char name[100];
};
MOVIE *list = NULL;
/*_______________________________________________________
*/
MOVIE *List_FindMovie(const char *movie_name){
MOVIE *tmp = list;
while (tmp != NULL) {
if (_stricmp(tmp->name, movie_name) == 0) {
return tmp;
}
tmp = tmp->next;
}
return NULL;
}
/*_______________________________________________________
*/
ACTOR *Movie_FindActor(MOVIE *movie,const char*actor_name){
ACTOR *tmpActor=movie->actors;
while(tmpActor){
if(_stricmp(tmpActor->name,actor_name)==0)
return tmpActor;
tmpActor=tmpActor->next;
}
return NULL;
}
/*_______________________________________________________
*/
int List_ActorInfo(const char *actor_name){
MOVIE *tmp = list;
int nmovies=0;
printf("Actor '%s' participations:\n",actor_name);
while (tmp != NULL) {
if(Movie_FindActor(tmp,actor_name)){
nmovies++;
printf("\t- %s\n",tmp->name);
}
tmp = tmp->next;
}
if(nmovies)
printf("\t Total: %d movies\n\n",nmovies);
else
printf("\t None\n\n");
return nmovies;
}
/*_______________________________________________________
*/
ACTOR *NewActor(const char*actor_name){
ACTOR *NewActor=calloc(1,sizeof(ACTOR));
strcpy(NewActor->name,actor_name);
return NewActor;
}
/*_______________________________________________________
*/
ACTOR *Movie_AddActor(MOVIE *movie,ACTOR *NewActor){
if(!movie->actors){
movie->actors=NewActor;
}else{
ACTOR *prevActor=NULL,*current=movie->actors;
while(_stricmp(current->name,NewActor->name)<0){
prevActor=current;
current=current->next;
if(!current)break;
}
NewActor->next=current;
if(prevActor)
prevActor->next=NewActor;
else
movie->actors=NewActor;
}
return NewActor;
}
/*_______________________________________________________
*/
MOVIE * List_AddMovie(const char *movie_name,genre type){
MOVIE *movie,*tmpMovie;
if(movie=List_FindMovie(movie_name)) return 0;
movie=calloc(1,sizeof(MOVIE));
strcpy(movie->name,movie_name);
movie->type=type;
if(!list)
list=movie;
else{
tmpMovie=list;
while(tmpMovie->next)
tmpMovie=tmpMovie->next;
tmpMovie->next=movie;
}
return movie;
}
/*_______________________________________________________
*/
void Movie_PrintActors(MOVIE *movie){
ACTOR *actor=movie->actors;
printf("Actors in Movie '%s':\n",movie->name);
while(actor){
printf("\t%s\n",actor->name);
actor=actor->next;
}
printf("\n");
return;
}
/*_______________________________________________________
*/
int main(){
MOVIE *mv;
List_AddMovie("Dogs",0);
mv=List_AddMovie("Dragons",0);
if(!mv){
printf("failed to add movie\n");
exit(-1);
}
Movie_AddActor(mv,NewActor("Z"));
Movie_AddActor(mv,NewActor("C"));
Movie_AddActor(mv,NewActor("A"));
Movie_AddActor(mv,NewActor("Cat8"));
Movie_PrintActors(mv);
mv=List_FindMovie("Dogs");
Movie_AddActor(mv,NewActor("Dog1"));
Movie_AddActor(mv,NewActor("Dog3"));
Movie_AddActor(mv,NewActor("Dog6"));
Movie_AddActor(mv,NewActor("Cat8"));
Movie_PrintActors(mv);
List_ActorInfo("Bruce Lee");
List_ActorInfo("Cat8");
return 0;
}