【问题标题】:Stack around the variable 'returnedstring' was corrupted变量“returnedstring”周围的堆栈已损坏
【发布时间】:2021-01-13 18:47:42
【问题描述】:

我正在尝试编写一个函数,该函数将返回每个单词中最大的 ASCII 字母。

所以我的字符串是 { "hello", "and", "good", "morniny" }; 我的返回值应该是“onoy”。

我正在为此苦苦挣扎,并不断收到我的变量“returnedstring”已损坏的错误:

围绕变量“returnedstring”的堆栈已损坏。

我在“MaxLetterToNewString”函数的最后一行收到此错误。 我尝试了许多解决方法,甚至释放了这个变量。 为什么会出现此错误?

我应该怎么做才能修复它?

本来我是用函数来返回值的,但是由于 它没有用,我想在 a 中获得价值 我称为“jr”(JustReturn)的新变量。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char MaxLetterToNewString(char *str[], int size, char *jr);

void main()
{
    char* blabla = " ";
    char* arr[] = { "hello", "and", "good", "morniny" };
    //char newarr[] = { NULL };
    char newarr;
    int size = 0;
    size = sizeof(arr) / sizeof(char*);
    //*newarr = (char*)malloc((size+1) * sizeof(char));
    newarr = MaxLetterToNewString(arr, size, *blabla);
    if (*arr == '\0')
        printf("Memory not allocated");
    else
        puts(*arr);
    free(*arr);
}

char MaxLetterToNewString(char *str[], int size,char *jr)
{
    int wordsize, letterstillnow = 0;
    char returnedstring[] = {NULL};
    char resultarr = '\0';
    for (int k = 0; k < size; k++)
    {
        wordsize = strlen(str[k]);
        for (int i = 0, j = i + 1; j < wordsize; i++, j++)
        {
            if (str[k][i] >= str[k][j])
                resultarr = str[k][i];
            else
                resultarr = str[k][j];
        }
        returnedstring[k] = resultarr;
        returnedstring[k + 1] = '\0';
    }
    jr = returnedstring;
}

【问题讨论】:

  • char returnedstring[]={NULL}; 不会分配足够的内存,函数调用者也不能使用它(如果这是有意的话)。函数本身不返回值,请查看编译器警告。
  • 最终free(*arr); in main 也不会对你有任何好处。

标签: c memory


【解决方案1】:

观察数组在内存中的存储方式(数组元素按顺序存储)以及字符数组是什么,即一系列以空字符结尾的字符,可以直观地了解以下解决方案:

将单词数组视为字符序列,'\0' 作为单词之间的分隔符。扫描序列,同时检查当前单词的结尾,即'\0' 字符。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *MaxLetterToNewString(char **str, int size) {
    char *result = malloc((size + 1) * sizeof(*result));

    int nullCounter = 0, max = 0, i = 0;
    char c;

    while (nullCounter < size) {
        c = *(*(str + nullCounter) + i++);
        if (c == '\0') { // we reached the end of the word
            i = 0;
            ++nullCounter;
            result[nullCounter - 1] = max;
            max = 0;
        } else if (c > max)
            max = c;
    }

    result[nullCounter] = '\0';
    return result;
}

void main() {
    char* arr[] = {"hello", "and", "good", "morniny"};

    int size = sizeof(arr) / sizeof(char*);
    char *result;
    result = MaxLetterToNewString(arr, size);
    printf("%s\n", result);

    free(result);
}

【讨论】:

  • @WhozCraig 由于我没有在任何地方更改str 指针,因此它始终指向数组的开头,i 表示距开头的偏移量。我已经测试了几次,它工作得很好。当然,我可能遗漏了一些东西,但现在我在这里没有看到问题。
  • i 表示相对于*str 的偏移量,它是指针序列中的第一个 字符串。绝对不能保证参与该指针数组的字符串文字在内存中是连续的。这就是我提到的问题。如果上面的代码有效,那是幸运的,而不是定义的行为。
  • @WhozCraig 感谢您的澄清。我的解决方案基于错误的假设,即不仅指针而且它们引用的数据都存储在连续的内存块中。更新了我的代码以反映这一点。
猜你喜欢
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 2012-11-08
  • 2019-09-04
  • 2020-07-26
  • 1970-01-01
相关资源
最近更新 更多