c -使用realloc获得段错误



我想解决下面这个问题,这个问题最近出现在我朋友的大学考试中(现在考试结束了,试卷也发了)

开发一个C程序来管理歌曲的播放列表,其中每首歌曲都有一个标题和持续时间(以秒为单位)。使用两个独立的动态分配数组来存储标题和持续时间。实现用户定义的函数,使用指针算术来添加、删除、更新和显示播放列表信息。(10分)

我做了以下尝试:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const size_t MAX_NAME_LENGTH = 20;
size_t number_of_songs = 0;
char* names_of_songs;
int* durations;
void add(char* name_of_song, int duration) {
number_of_songs++;
names_of_songs = realloc(name_of_song, MAX_NAME_LENGTH * number_of_songs);
durations = realloc(durations, number_of_songs * sizeof(int));
int start_location = ((number_of_songs - 1) * MAX_NAME_LENGTH) + 1;
char* name_location = &name_of_song[start_location];
strncpy(name_location, name_of_song, MAX_NAME_LENGTH);
names_of_songs[start_location + strlen(name_of_song) + 1] = 0;
durations[number_of_songs - 1] = duration;
}
void display() {
for (size_t i = 0; i < number_of_songs; i++) {
int position_in_name = 0;
int start_location = (i * MAX_NAME_LENGTH) + 1;
char character = 1;
printf("Name: ");
while (character != 0) {
character = names_of_songs[start_location++];
printf("%c", character);
}
printf(", Duration: %d secn", durations[i]);
}
}
int main(int argc, char const *argv[]) {
names_of_songs = malloc(1);
durations = malloc(1);
display();
add("Something", 2);
display();
add("Something else", 32);
display();
add("boring song", 4);
display();
free(names_of_songs);
free(durations);
return 0;
}

当我运行它时,我得到一个分段错误。使用我的调试器,当add()试图调整新歌标题时,似乎第一次运行realloc()时会发生这种情况。发生了什么,我该如何解决?

另外,我如何调试这样的东西?

  1. relloc()用于调整动态内存大小。最简单的解决方法就是允许全局变量初始化默认值为0。

  2. realloc()的返回值分配给临时值,否则如果realloc()失败,将会泄漏内存。

  3. 当你指的是names_of_songs时,在第一个realloc()name_of_song中使用了不正确的变量。

  4. 使用符号常量代替const值。在堆栈上分配内存时需要前者,否则它们将成为vla。

  5. + 1的起始位置错误

  6. 在每个add()之后删除display(),因为它令人困惑(对我来说)。

  7. (不固定)对于names_of_songs考虑使用char指针数组(即char **names_of_songs):names_of_songs[number_of_songs] = strndup(name_of_songs, MAX_NAME_LENGTH)这更容易,你没有浪费空间。

  8. (未修复)如果你真的想使用char数组,考虑用指向char数组的指针(*p)[MAX_NAME_LENGTH]索引它,以便编译器为你缩放指针。

  9. display():只打印字符串而不是单独打印每个字符更容易。然后,您可以将所有printf()调用合并为一个。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 20
size_t number_of_songs;
char* names_of_songs;
int* durations;
void add(char* name_of_song, int duration) {
char *tmp = realloc(names_of_songs, MAX_NAME_LENGTH * (number_of_songs + 1));
if(!tmp) {
printf("malloc failedn");
return;
}
names_of_songs = tmp;
strncpy(names_of_songs + number_of_songs * MAX_NAME_LENGTH, name_of_song, MAX_NAME_LENGTH);
names_of_songs[number_of_songs * MAX_NAME_LENGTH + strlen(name_of_song)] = '';
int *tmp2 = realloc(durations, sizeof *tmp2 * (number_of_songs + 1));
if(!tmp2) {
printf("malloc failedn");
return;
}
durations = tmp2;
durations[number_of_songs] = duration;
number_of_songs++;
}
void display() {
for (size_t i = 0; i < number_of_songs; i++)
printf("Name: %s, Duration %d secn",
names_of_songs + i * MAX_NAME_LENGTH,
durations[i]
);
}
int main() {
add("Something", 2);
add("Something else", 32);
add("boring song", 4);
display();
free(names_of_songs);
free(durations);
}

示例输出:

Name: Something, Duration: 2 sec
Name: Something else, Duration: 32 sec
Name: boring song, Duration: 4 sec

相关内容

  • 没有找到相关文章

最新更新