我又有一个关于 C 的工作原理的问题。(由 VS2012 编译的 ANSI-C)
我正在将独立程序 (.exe) 重构为 .dll。到目前为止,这工作得很好,但是在记录日志时我偶然发现了一些问题。让我解释:
原始程序 - 在运行时 - 写入日志文件并将信息打印到屏幕上。由于我的 dll 将在网络服务器上运行,许多人同时访问
- 没有真正的机会正确处理日志文件(并在它们之后清理)
- 没有任何人会看到的控制台窗口
因此,我的目标是将要放入日志文件或屏幕上的所有内容写入类似字符串的变量(我知道 C 中没有字符串),然后我可以稍后将 requet 传递给调用者(也是dll,但用 C# 编写)。
因为在 C 中这样的事情是不可能的:
char z88rlog;
z88rlog="First log-entry\n";
z88rlog+="Second log-entry\n";
我有两种可能:
char z88rlog[REALLY_HUGE];
- 动态分配内存
在我看来,第一种方法是被忽略的,因为:
- 内存的潜在浪费是相当巨大的
- 我仍然可能需要比 更多的内存
REALLY_HUGE
,从而造成缓冲区溢出
这让我有了第二种方式。我已经为此做了一些工作,并提出了两个解决方案,其中任何一个都不能正常工作。
/* Solution 1 */
void logpr(char* tmpstr)
{
extern char *z88rlog;
if (z88rlog==NULL)
{
z88rlog=malloc(strlen(tmpstr)+1);
strcpy(z88rlog,tmpstr);
}
else
{
z88rlog=realloc(z88rlog,strlen(z88rlog)+strlen(tmpstr));
z88rlog=strcat(z88rlog,tmpstr);
}
}
在解决方案 1 中(等于解决方案 2,您会发现)我通过char tmpstr[255];
. 我的“日志文件”z88rlog
是全局声明的,所以我需要extern
访问它。然后我检查是否已为z88rlog
. 如果不是,我分配内存的大小为我的日志条目(+1 为 my \0
)并将内容复制tmpstr
到z88rlog
. 如果是的话,我会重新分配内存的大小+ (+1)z88rlog
的长度。tmpstr
然后使用 . 将两个“字符串”连接起来strcat
。使用断点和直接窗口我获得了以下输出:
z88rlog
0x00000000 <Schlechtes Ptr>
z88rlog
0x0059ef80 "start Z88R version 14OS"
z88rlog
0x0059ef80 "start Z88R version 14OS
opening file Z88.DYNÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍýýýý««««««««þîþîþîþ"
它显示了三个连续的 logpr 调用(strcpy
/之前的断点strcat
)。最后无法区分的乱码是由于内存分配造成的。之后 VS 发出一条错误消息,指出某些原因导致调试器在realloc.c
. 因为这显然行不通,所以我炮制了我的绝妙解决方案 2:
/* Solution 2 */
void logpr(char* tmpstr)
{
extern char *z88rlog;
char *z88rlogtmp;
if (z88rlog==NULL)
{
z88rlog=malloc(strlen(tmpstr)+1);
strcpy(z88rlog,tmpstr);
}
else
{
z88rlogtmp=malloc(strlen(z88rlog)+strlen(tmpstr+1));
z88rlogtmp=strcat(z88rlog,tmpstr);
free(z88rlog);
z88rlog=malloc(strlen(z88rlogtmp)+1);
memcpy(z88rlog,z88rlogtmp,strlen(z88rlogtmp)+1);
free(z88rlogtmp);
}
}
在这里,我的目标是创建我的日志文件的副本,释放原件的内存为新大小的原件创建新内存并将内容复制回来。并且不要忘记释放临时副本,因为它是通过 malloc 分配的。当它到达时立即崩溃free
,再次告诉我堆可能已损坏。
因此,让我们暂时免费评论。这确实工作得更好 - 让我松了一口气 - 但是在构建日志字符串时突然并非所有字符都z88rlogtmp
被复制。但一切仍然正常工作。直到突然我再次被告知堆可能被破坏并且调试器在_heap_alloc (size_t size)
in malloc.c
size
has的末尾放置了一个断点 - 根据调试器 - 1041的值。
因此,我有 2 种(或 3 种)方法想要实现这种“字符串增长”,但没有一种有效。给我大小的错误可能会让我得出数组已经变大的结论吗?我希望我能很好地解释我想做什么,有人可以帮助我:-)提前谢谢!
对Maybee具有讽刺意味的是,我应该去为计算机购买一些新堆。它适合 RAM 插槽吗?谁能推荐一个好品牌?讽刺