【发布时间】:2017-10-13 06:03:10
【问题描述】:
我正在尝试使用合并排序算法进行字符串排序。这是我的相关代码:
void sortCities(EXPEDITION *expedition, int expeditionNumber)
{
int i;
int j;
char **tmp;
tmp = (char**)malloc((expeditionNumber) * sizeof(char*));
for (i = 0; i < expeditionNumber; i++) {
tmp[i] = (char*)malloc(15 * sizeof(char));
}
for (i = 0, j = 0; i < expeditionNumber; i++, j++) {
tmp[j] = expedition[i].city;
}
for (i = 0; i < expeditionNumber; i++) {
printf("%s\n", tmp[i]);
}
mergeSort(tmp, 0, expeditionNumber);
for (i = 0; i < expeditionNumber; i++) {
printf("%s\n", tmp[i]);
}
}
void mergeSort(char** array, int first, int last)
{
int middle;
if (first < last) {
middle = (first + last) / 2;
mergeSort(array, first, middle);
mergeSort(array, middle + 1, last);
merge(array, first, middle + 1, middle, last);
}
}
void merge(char** array, int first1, int first2, int last1, int last2)
{
int i;
int j;
int k;
char **newArray;
newArray = (char**)malloc((last2 - first1 + 1) * sizeof(char*));
for (i = 0; i < last2 - first1 + 1; i++) {
newArray[i] = (char*)malloc(15 * sizeof(char));
}
j = first2;
i = first1;
k = 0;
while (i < last1 && j < last2) {
if (strcmp(array[i], array[j]) > 0) {
strcpy(newArray[k++], array[j++]);
}
else {
strcpy(newArray[k++], array[i++]);
}
}
if (i < last1) {
while (i < last1) {
strcpy(newArray[k++], array[i++]);
}
}
if (j < last2) {
while (j < last2) {
strcpy(newArray[k++], array[j++]);
}
}
for (i = first1, j = 0; i < last2; i++, j++) {
strcpy(array[i], newArray[j]);
}
}
问题是 tmp 将空值返回给 sortCities 函数。在将 tmp 发送到 mergeSort 之前,我检查了它的内容,我看到它复制正确(来自 expedition.city)。可能是什么原因?
编辑:我通过编写“array[i] = newArray[j];”来处理这个问题insead "strcpy(array[i], newArray[j])"。但现在它没有正确排序。我想我应该使用 "
【问题讨论】:
-
您是否尝试过在调试器中逐行逐行执行代码,以确保它确实按照您的意图进行操作?我建议您花点时间阅读 Eric Lippert 的 How to debug small programs,并学习如何使用调试器。
-
其实这个没那么短,1000行左右。是的,我尝试了另一种调试方法,它采用了代码注释行,所以我可以通过在 sortCities 函数中打印出来来查看出了什么问题以及我真正得到了什么。谢谢
-
好吧,如果你需要帮助你需要提供一个minimal reproducible example,你的问题不完整,我们不知道你的数据结构,或者你如何影响它等等。你的问题可能在您的程序中的任何位置。
-
即使是一百万行代码,正确的解决方案仍然是使用调试器单步执行。您可以从“printf 调试”(也称为跟踪)开始缩小需要调试的代码部分,但最终最好的方法是设置断点,并逐行执行代码。调试并不容易,通常恰恰相反。不幸的是,即使只是将编程作为一种爱好,它也是一项必需的技能,如果这是你的工作,那就更是如此。
-
还要注意,您在
for (i = 0; i < expeditionNumber; i++) { tmp[i] = (char*)malloc(15 * sizeof(char)); } for (i = 0, j = 0; i < expeditionNumber; i++, j++) { tmp[j] = expedition[i].city; }处泄漏内存——在第一个循环中,您分配由tmp[i]指针引用的内存;在第二个中,您使用expedition[i].city中的值覆盖对内存的唯一引用,从而丢弃内存。您不能在 C 中复制带有赋值的字符串。