首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数返回导致顶级大小损坏的字符串。

函数返回导致顶级大小损坏的字符串。
EN

Stack Overflow用户
提问于 2022-01-20 06:17:37
回答 1查看 84关注 0票数 0

我正在尝试编写一个调用外部库(?)的程序。(我不确定我在这里使用的术语是否正确),我也是为了清理提供的字符串而编写的。例如,如果要向我的main.c程序提供一个字符串,如:

asdfFAweWFwseFL Wefawf JAWEFfja FAWSEF

它将调用externalLibrary.c中的一个函数(让我们现在称它为externalLibrary_Clean ),该函数将接受字符串,并以大写形式返回所有字符,没有空格:

ASDFFAWEWFWSEFLWEFAWFJAWEFFJAFAWSEF

最疯狂的是我有个工作..。只要我的字符串长度不超过26个字符。一旦我添加了第27个字符,我就会出现一个错误,上面写着malloc(): corrupted top size

这是externalLibrary.c

代码语言:javascript
运行
复制
#include "externalLibrary.h"
#include <ctype.h>
#include <malloc.h>
#include <assert.h>
#include <string.h>

char * restrict externalLibrary_Clean(const char* restrict input) {
    // first we define the return value as a pointer and initialize
    // an integer to count the length of the string
    char * returnVal = malloc(sizeof(input));
    char * initialReturnVal = returnVal; //point to the start location

    // until we hit the end of the string, we use this while loop to
    // iterate through it
    while (*input != '\0') {
        if (isalpha(*input)) {  // if we encounter an alphabet character (a-z/A-Z)
                                // then we convert it to an uppercase value and point our return value at it
            *returnVal = toupper(*input);
            returnVal++; //we use this to move our return value to the next location in memory
            
        }
        input++; // we move to the next memory location on the provided character pointer
    }

    *returnVal = '\0'; //once we have exhausted the input character pointer, we terminate our return value

    return initialReturnVal;
}

int * restrict externalLibrary_getFrequencies(char * ar, int length){
    static int freq[26];
    for (int i = 0; i < length; i++){
        freq[(ar[i]-65)]++;
    }
    return freq;
}

它的头文件(externalLibrary.h):

代码语言:javascript
运行
复制
#ifndef LEARNINGC_EXTERNALLIBRARY_H
#define LEARNINGC_EXTERNALLIBRARY_H

#ifdef __cplusplus
extern "C" {
#endif

char * restrict externalLibrary_Clean(const char* restrict input);
int * restrict externalLibrary_getFrequencies(char * ar, int length);

#ifdef __cplusplus
}
#endif

#endif //LEARNINGC_EXTERNALLIBRARY_H

我的main.c文件是从所有动作发生的地方开始的:

代码语言:javascript
运行
复制
#include <stdio.h>
#include "externalLibrary.h"

int main() {
    char * unfilteredString = "ASDFOIWEGOASDGLKASJGISUAAAA";//if this exceeds 26 characters, the program breaks 
    char * cleanString = externalLibrary_Clean(unfilteredString);
    //int * charDist = externalLibrary_getFrequencies(cleanString, 25); //this works just fine... for now

    printf("\nOutput: %s\n", unfilteredString);
    printf("\nCleaned Output: %s\n", cleanString);
    /*for(int i = 0; i < 26; i++){
        if(charDist[i] == 0){

        }
        else {
            printf("%c: %d \n", (i + 65), charDist[i]);
        }
    }*/

    return 0;
}

我非常精通Java编程,我正试图将我的知识转化为C语言,因为我希望更详细地了解我的计算机是如何工作的(并且对内存等事情有更好的控制)。

如果我要用Java解决这个问题,它就像创建两个类文件一样简单:一个名为main.java,另一个名为externalLibrary.java,在那里我将拥有static String Clean(string input),然后在main.java中使用String cleanString = externalLibrary.Clean(unfilteredString)调用它。

很明显,这不是C的工作方式,,但我想了解是如何运行的(以及为什么我的代码会因为损坏的顶部大小而崩溃)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-25 12:03:28

bug是这样一行:

代码语言:javascript
运行
复制
char * returnVal = malloc(sizeof(input));

它之所以是一个bug,是因为它要求分配足够大的空间来存储指针,这意味着64位程序中有8个字节。您想要做的是分配足够的空间来存储修改后的字符串,您可以使用下面的行来这样做:

代码语言:javascript
运行
复制
char *returnVal = malloc(strlen(input) + 1);

所以,问题的另一部分是,为什么当字符串小于26个字符时,程序不会崩溃。原因是允许malloc比调用方请求的稍多一些。

在您的示例中,消息" malloc ():corrupted top size“表明您使用的是libc,这是Linux上的默认设置。在64位进程中,malloc的变体总是给出至少0x18 (24)字节(大小/状态的最小块大小0x20-8字节)。在分配比“顶级”分配之前的特定情况下,写过分配结束后的“顶级”大小将遭到重击。

如果您的字符串大于23 (0x17),您将开始关闭后续分配的大小/状态,因为还需要1字节来存储尾空。但是,任何字符串23个或更短的字符都不会造成问题。

至于为什么你没有得到一个有26个字符的字符串的错误,要想回答这个错误,你必须看到一个有26个字符的字符串的精确程序,这样才能给出一个更精确的答案。例如,如果程序提供了一个包含3个空格的26个字符的输入,这将只需要分配26 +1-3=24个字节,这是合适的。

如果您对该级别的细节不感兴趣,那么修复malloc调用以请求适当的数量将修复您的崩溃。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70781593

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档