我需要画一行字符,只要我想要。所以我为此目的编写了一个函数:
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) 时,它不断崩溃。
这段代码有什么问题?
不要将
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
,而且实际上效果更好。
分配的内存开始包含垃圾。将其设置为空字符串,例如这样:
compLine[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