我似乎无法找到一个与我正在做的完全匹配的问题,所以这里就是这样。下面是我的C应用程序的缩减版本,直到问题所在。我知道这是丑陋的代码并且缺少一些错误检查但是我只是想弄清楚这个问题。如上所示,下面的示例应将所有'A'转换为'BCDE'。代码中的注释描述了该问题。 (runMe首先执行)
int runMe2(char *in, char **buffer) {
long x;
long b_size = 0;
long i_size = 1000;
long i = 0;
char t_buffer[1006];
// Initial malloc small as it will grow
*buffer = (char *)malloc(2*sizeof(char));
strcpy(*buffer, "");
for (x = 0; x < 999; x++)
t_buffer[x] = 0;
for (x = 0; x < strlen(in); x++) {
if (i >= i_size) {
char *r_buffer;
b_size = b_size + 1006*sizeof(char);
i_size = 0;
// Here is where the problem is.
// The first time through, i=1000, b_size=1006 and everything is fine
// The second time throgh, i=1004, b_size=2012 and the heap crashes on the realloc
r_buffer = (char *)realloc(*buffer, b_size);
if (r_buffer == NULL)
exit(0);
*buffer = r_buffer;
strcat(*buffer, t_buffer);
for (x = 0; x < 999; x++)
t_buffer[x] = 0;
}
if (in[x] == 'A') {
t_buffer[i++] = 'B';
t_buffer[i++] = 'C';
t_buffer[i++] = 'D';
t_buffer[i++] = 'E';
}
}
}
int runMe() {
char *out;
char in[30000];
int x = 0;
// Set up a 29,999 character string
for (x = 0; x < 30000; x++)
in[x] = 'A';
in[29999] = 0;
// Send it as pointer so we can do other things here
runMe2(in, &out);
// Eventually, other things will happen here
free(out);
}
答案 0 :(得分:3)
if (i >= i_size) {
...
i_size = 0;
...
}
if (in[x] == 'A') {
t_buffer[i++] = 'B';
...
这不可能是正确的。如果t_buffer
比原始in
长,那么您将在i_size
结束时写作。您可能需要重置i
,而不是i_size
。
然后,当你不能保证它被正确地以空值终止时,你正在使用带有t_buffer
的字符串函数 - 你初始化前1000个值,但是覆盖循环中的值。如果你要使用strcat
和朋友,你需要更加小心,确保它保持空终止。但是使用memcpy
会导致更简单的代码,因为您知道所涉及的数组的长度。
for (x = 0; x < strlen(in); x++) {
...
for (x = 0; x < 999; x++)
...
t_buffer[x] = 0;
答案 1 :(得分:2)
只是为了好玩,这里有一个不同的算法,它比你的更加简单:
int runMe2(char *in, char **buffer)
{
// Count number of A's
int number_of_As = 0;
int i, j;
for (i = 0; 0 != in[i]; i++) {
if (in[i] == 'A') {
number_of_As += 1;
}
}
// If number_of_As == 0, you can just do a strdup here and return
// Because of 1st loop, i == strlen(in), no need to call strlen
long bytes = (i - number_of_As + (number_of_As * 4) + 1) * sizeof(char);
// Error check here
// Only 1 memeory allocation needed
*buffer = (char *)malloc(bytes);
// Simple copy loop
for (i = 0, j = 0; 0 != in[i]; i++) {
// If it's an A replace
if (in[i] == 'A') {
(*buffer)[j++] = 'B';
(*buffer)[j++] = 'C';
(*buffer)[j++] = 'D';
(*buffer)[j++] = 'E';
}
// Not an A, just copy
else {
(*buffer)[j++] = in[i];
}
}
// Null terminate
(*buffer)[j] = 0;
return j;
}