strcat 使程序崩溃(0xc0000005)

问题描述 投票:0回答:3

我需要画一行字符,只要我想要。所以我为此目的编写了一个函数:

void fDrawLine(int length)
{
    int i;
    char * compLine = (char *) malloc(WINDOW_WIDTH + 2);

    for(i = 0; i < length; i++)
        strcat(compLine, "-");

    fDrawSpacedMessage(compLine, -1, TRUE);
}

WINDOW_WIDTH
定义为
80
fDrawSpacedMessage
是另一个打印文本居中等的功能

它正在完美构建,没有错误,没有警告。但在运行时,一切正常,但如果执行

fDrawLine
,程序就会崩溃并给出错误代码
0xc0000005
。我知道这是关于内存分配的,但我已经初始化了
compLine
字符串。

我尝试过一些事情;我以为是另一个函数造成的,所以我隔离了

fDrawLine
,但崩溃仍在继续。使用
compLine[0] = 0;
compLine[WINDOW_WIDTH] = {0};
更改初始化没有帮助。

它与我的另一台运行 Ubuntu 的机器配合得很好,带有最新的 gcc,但是当在 Windows 上使用 Code::Blocks (MinGW) 时,它不断崩溃。

这段代码有什么问题?

c string pointers for-loop strcat
3个回答
1
投票

不要将

compLine
声明为指针,因为你不需要它,而且实际上你的函数中有内存泄漏,首先这样声明
compLine

char compLine[1 + WINDOW_WIDTH] = {0}; // strings need an extra byte at the end to mark the end.

然后使用

memset
设置
'-'
字符,如下所示

memset(compLine, '-', length);

当然,请检查

length <= WINDOW_WIDTH

这个功能是你固定的,你可以试试

void fDrawLine(int length)
{
    char compLine[1 + WINDOW_WIDTH] = {0}; // initialized so that last byte is '\0'.
    if (length > WINDOW_WIDTH)
        length = WINDOW_WIDTH;
    memset(compLine, '-', length);        
    fDrawSpacedMessage(compLine, -1, TRUE);
}

除了使用

strcat
这种方式是个坏主意之外,你还可以这样做

char *compLine = malloc(1 + length); // the last extra '\0' byte.
if (compLine == NULL) // malloc returns NULL on failure to allocate memory
    return; // so we must abort this function in that case.
for(i = 0; i < length; i++)
    compLine[i] = '-';
compLine[length] = '\0';

fDrawSpacedMessage(compLine, -1, TRUE);
free(compLine);

在这种情况下你也可以使用

memset
,而且实际上效果更好。


1
投票

分配的内存开始包含垃圾。将其设置为空字符串,例如这样:

compLine[0] = '\0';

0
投票

下面的代码有一些问题

void fDrawLine(int length)
{
    int i;
    char * compLine = (char *) malloc(WINDOW_WIDTH + 2);

    for(i = 0; i < length; i++)
        strcat(compLine, "-");

    fDrawSpacedMessage(compLine, -1, TRUE);
}

首先,

length
参数至少应为
unsigned int
,因为负长度没有意义。理想情况下,您应该使用
size_t
i
也是如此。

接下来,您不会保护自己免受

length
无效值的影响。隐含的契约是 0 <=
length
<=
WINDOW_WIDTH
- 使其显式化。

您使用动态分配的内存会导致内存泄漏,因为您在调用

fDrawSpacedMessage()
后没有释放它。

最后,

strcat
附加单个字符有点过分了。

将所有这些放在一起,这是一个替代实现。

void fDrawLine(size_t length)
{
    size_t actual_length = length <= WINDOW_WIDTH ? length : WINDOW_WIDTH;
    char compLine[WINDOW_WIDTH+2];

    memset(compLine, '-', actual_length);
    compline[actual_length] = '\0';
    fDrawSpacedMessage(compLine, -1, TRUE);
}

我已将

compline
留在
WINDOW_WIDTH+2
,因为我猜测
fDrawSpacedMessage
添加了换行符。

如果仍然崩溃,问题出在

fDrawSpacedMessage

© www.soinside.com 2019 - 2024. All rights reserved.