我正在尝试编写一个调用外部库(?)的程序。(我不确定我在这里使用的术语是否正确),我也是为了清理提供的字符串而编写的。例如,如果要向我的main.c
程序提供一个字符串,如:
asdfFAweWFwseFL Wefawf JAWEFfja FAWSEF
它将调用externalLibrary.c
中的一个函数(让我们现在称它为externalLibrary_Clean
),该函数将接受字符串,并以大写形式返回所有字符,没有空格:
ASDFFAWEWFWSEFLWEFAWFJAWEFFJAFAWSEF
最疯狂的是我有个工作..。只要我的字符串长度不超过26个字符。一旦我添加了第27个字符,我就会出现一个错误,上面写着malloc(): corrupted top size
。
这是externalLibrary.c
#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
):
#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
文件是从所有动作发生的地方开始的:
#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的工作方式,,但我想了解是如何运行的(以及为什么我的代码会因为损坏的顶部大小而崩溃)
发布于 2022-02-25 12:03:28
bug是这样一行:
char * returnVal = malloc(sizeof(input));
它之所以是一个bug,是因为它要求分配足够大的空间来存储指针,这意味着64位程序中有8个字节。您想要做的是分配足够的空间来存储修改后的字符串,您可以使用下面的行来这样做:
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调用以请求适当的数量将修复您的崩溃。
https://stackoverflow.com/questions/70781593
复制相似问题