【问题标题】:Exception thrown: read access violation. **head** was 0xCCCCCCCC. occurred抛出异常:读取访问冲突。 **head** 是 0xCCCCCCCC。发生了
【发布时间】:2019-09-11 14:47:24
【问题描述】:

我正在用 C 编写一个链接列表。这是我的代码。我在这里看不到任何逻辑错误,但是在while循环中打印时,在打印最后一个节点后它不会跳出循环而是继续循环然后给我这个错误“抛出异常:读取访问冲突。head 是 0xCCCCCCCC。发生在循环中的“头”指针上。

// ass0.c
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC // need this to get the line identification
//_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF); // in main, after local declarations
//NB must be in debug build
#include <crtdbg.h>
#include <stdio.h>
#include <string.h>
typedef enum { FALSE = 0, TRUE } BOOL;
struct Frame {
char* frameName;
struct Frame* pNext;
};
typedef struct {
char* animationName;
struct Frame* frames;
}Animation;
// Forward declarations
void InitAnimation(Animation*);
void InsertFrame(Animation*);
//void DeleteFrame(Animation*);
//void EditFrame(Animation*);
void ReportAnimation(Animation*);
//void CleanUp(Animation*);
int main(void)
{
char response;
BOOL RUNNING = TRUE;
Animation RG;
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
InitAnimation(&RG);
while (RUNNING)
{
    printf("MENU\n 1. Insert a Frame at the front\n 2. Delete last Frame\n 3. Edit a Frame\n 4. Report the Animation\n 5. Quit\n");
    scanf("%c", &response);
    switch (response)
    {
    case '1':InsertFrame(&RG); break;
    //case '2':DeleteFrame(&RG); break;
    //case '3':EditFrame(&RG); break;
    case '4':ReportAnimation(&RG); break;
    //case '5':RUNNING = FALSE; CleanUp(&RG); break;
    default:printf("Please enter a valid option\n");
    }
}
return 0;
  }

  void InitAnimation(Animation* newAnimation) {
newAnimation = malloc(sizeof(Animation));
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
 }

 void InsertFrame(Animation* animation) {
printf("Insert a Frame in the Animation\n");
char fName[50];
printf("Please enter the Frame Name: ");
scanf("%s", fName);

struct Frame *newFrame; 
newFrame = malloc(sizeof(struct Frame));
int nameSize = strlen(fName);
newFrame->frameName = malloc(nameSize + 1);
strcpy(newFrame->frameName, fName);
newFrame->pNext = 0;

//struct Frame* head;

if (animation->frames == NULL) 
    animation->frames = newFrame;
    //head = animation->frames;
    //head->pNext = NULL;
    //head = animation->frames;


else {
    //head = animation->frames;
    newFrame->pNext = animation->frames;
    animation->frames = newFrame;

    /*while (head != NULL) {
        newFrame->pNext = *head;
        animation->frames = newFrame;
        printf("%s", *head->frameName);
        head = head->pNext;
    }*/

    //head = animation->frames;
    printf("\n");
}
}

void ReportAnimation(Animation* animation) {
printf("Animation name is Animation_1\n");
printf("Report the Animation\n");
struct Frame* head = animation->frames;
//printf("%s\n", head->frameName);

while (head) {
    printf("%s\n", head->frameName);
    head = head->pNext;
}
//printf("%d", count);
  }

【问题讨论】:

  • 请通过编辑您的帖子来修正代码格式。此代码不可读。
  • 贴出的代码编译失败!在(许多)其他问题中,它缺少以下语句:#include &lt;stdlib.h&gt; 用于 malloc() 的原型之类的东西。
  • 强烈建议将此语句:typedef enum { FALSE = 0, TRUE } BOOL; 替换为:#include &lt;stdbool.h&gt;(暴露falsetruebool 等)注意:暴露的项目都是小写
  • 强烈建议删除所有CrtSetDbgFlag() 和相关调用
  • OT:为了便于阅读和理解:1) 请始终缩进代码。在每个左大括号“{”后缩进。在每个右大括号 '}' 之前取消缩进。建议每个缩进级别为 4 个空格。 2)单独的代码块:forifelsewhiledo...whileswitchcasedefault通过一个空行。 3) 通过 2 或 3 个空行分隔函数(保持一致)

标签: c list singly-linked-list c-strings


【解决方案1】:

至少函数InitAnimation没有意义

void InitAnimation(Animation* newAnimation) {
newAnimation = malloc(sizeof(Animation));
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
 }

因此整个程序是不正确的。

原始对象

Animation RG;
//...
InitAnimation(&RG);

未初始化。函数的参数只是被覆盖了。

由于定义,Animation 类型的对象已经在 main 中创建了

Animation RG;

你只需要初始化它的数据成员。

使用 malloc 调用删除语句

void InitAnimation(Animation* newAnimation) {
newAnimation->animationName = "Animation_1";
newAnimation->frames = NULL;
 }

通常你应该为数据成员animationName指向的字符串动态分配内存。

函数cam如下所示

int InitAnimation( Animation *newAnimation, const char *name ) 
{
    newAnimation->animationName = malloc( strlen( name ) + 1 );

    int success = newAnimation->animationName !+ NULL;

    if ( success )
    {
        strcpy( newAnimation->animationName, name );
        newAnimation->frames = NULL;
    }

    return success;
}

并像这样称呼

Animation RG;
//...
InitAnimation(&RG, "Animation_1" );

请注意,您需要在声明函数mallocfree 的地方包含标题&lt;stdlib.h&gt;

【讨论】:

  • 这解决了我的问题,谢谢。但是你能解释一下为什么我不应该在这里使用 malloc 作为参数吗?我不应该先为整个“动画”结构分配空间吗?
  • @SunZhuan 由于定义了 Animation RG;,因此已经在 main 中创建了 Animation 类型的对象。你只需要初始化它的数据成员。
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 2019-04-04
  • 1970-01-01
  • 2019-03-09
  • 1970-01-01
  • 2021-05-01
  • 2020-09-12
  • 1970-01-01
相关资源
最近更新 更多