老师,关于realloc函数

来源:9-5 字符串的拆分

张婧仪

2020-12-23

在一次错误中,realloc函数大小我写成了language_capacity,而不是sizeof(Language)*language_capacity,结果依然打印了出来。我很好奇,于是我就调试,发现realloc函数把之前的数据修改了,我想问的是,明明把之前的数据修改或者覆盖了,为什么还能打印出来?

http://img.mukewang.com/szimg/5fe2a48a09811dad09020494.jpg

这张图是执行Language *languages=malloc(sizeof(Language)*language_capacity);这段代码的内存分布

http://img.mukewang.com/szimg/5fe2a4fe09c1ed7809070484.jpg

这张图是在执行realloc函数前的内存分布,已经赋了三次值(前三行)。

http://img.mukewang.com/szimg/5fe2a5a909d5462b09050513.jpg

这张图是在执行realloc函数之后的内存分布,可以看到数据被修改了(紫色部分)

我就好奇为什么还能打印出C这个字母,因为C的地址已经被修改了呀(第一行的第7,8个字节)

另外,调试的时候我没有打印出C这个字母,因为一打印,就崩了。正常运行就能打印出。

代码:

#include <stdio.h>
#include <io_utils.h>
#include <stdlib.h>
#include <string.h>
int main(){
  char string[] = "C, 1972; C++, 1983; Java, 1995; Rust, 2010; Kotlin, 2011";
  typedef struct {
    char *name;
    int year;
  } Language;
  const char* language_break=";";
  const char* field_break=",";
  int language_capacity=3;
  int language_size=0;
  Language *languages=malloc(sizeof(Language)*language_capacity);
  if(!languages){
    abort();
  }
  char* next=strtok(string,field_break);
  while(next){
    Language language;
    language.name=next;
    next=strtok(NULL,language_break);
    if(next){
      language.year=atoi(next);
    }
    if(language_size+1>language_capacity){
      language_capacity*=2;
      languages=realloc(languages,language_capacity);
      if(!languages)
        abort();
    }
    languages[language_size++]=language;

    next=strtok(NULL,field_break);
  }
  PRINTLNF("%s",languages[0].name);//打印C这个字母
  free(languages);
  return 0;
}


写回答

1回答

bennyhuo

2020-12-23

恰好name的位置没改吧,你仔细看看,前面有几个字节的值没变

0
7
bennyhuo
回复
张婧仪
你在打印之前断点看下内存就明白了。
2020-12-23
共7条回复

C语言系统化精讲 重塑编程思想 打造坚实的开发基础

如果通向大牛的道路有捷径,那就是先学好C语言

2266 学习 · 858 问题

查看课程