我正在开发一个程序,它可以从输入文件中逐行读取文本。一旦读取了该行,程序就会颠倒该字符串中单词的顺序,将其打印到输出文件中,然后开始阅读下一行。我的程序只从一行中读取特定数量的字符,这意味着如果一行包含的字符多于该特定数量,所有这些都必须跳过,直到到达下一行。我的程序似乎工作得很好。
任务要求之一是使用动态分配的数组。这是我的主要问题所在。一旦我试图释放堆分配的内存,程序失败并显示错误消息:检测到堆损坏。一定是我在与他们合作时搞砸了什么。但我无法找到真实的的原因。
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 255
int readLine(FILE** stream, char** buffer, int* bufferSize);
void reverseString(char* buffer, char** reverse, int bufferSize, int lastLine);
int main(int argc, char** argv)
{
char* buffer = NULL;
char* reverse = NULL;
int bufferSize = 0;
int lastLine = 0;
FILE* intputStream = fopen(argv[1], "r");
FILE* outputStream = fopen(argv[2], "w");
if (intputStream == NULL || outputStream == NULL)
{
printf("Input or output file cannot be opened\n");
return 0;
}
while (!feof(intputStream))
{
lastLine = readLine(&intputStream, &buffer, &bufferSize);
reverse = (char*)malloc(sizeof(char) * bufferSize);
if (reverse != NULL)
{
reverseString(buffer, &reverse, bufferSize, lastLine);
fputs(reverse, outputStream);
}
}
fclose(intputStream);
fclose(outputStream);
free(buffer);
free(reverse);
return 0;
}
int readLine(FILE** stream, char** buffer, int* bufferSize)
{
char tempBuffer[BUFFER_SIZE] = { 0 };
int lastLine = 0;
if (*stream != NULL)
{
fgets(tempBuffer, BUFFER_SIZE, *stream);
char ignoredChar[100] = { 0 };
*bufferSize = strlen(tempBuffer);
// Ignoring in the same line left characters and checking if this is the last line
if (tempBuffer[(*bufferSize) - 1] != '\n')
{
fgets(ignoredChar, 100, *stream);
if (!feof(*stream))
lastLine = 1;
}
// Allocating memory and copying line to dynamically-allocated array
*buffer = (char*)malloc(sizeof(char) * (*bufferSize));
if (*buffer != NULL)
{
memcpy(*buffer, tempBuffer, (*bufferSize));
(*buffer)[(*bufferSize)] = '\0';
}
}
// Return whether or not the last line is read
return lastLine;
}
void reverseString(char* buffer, char** reverse, int bufferSize, int lastLine)
{
int startingValue = (lastLine ? bufferSize - 1 : bufferSize - 2);
int wordStart = startingValue, wordEnd = startingValue;
int index = 0;
while (wordStart > 0)
{
if (buffer[wordStart] == ' ')
{
int i = wordStart + 1;
while (i <= wordEnd)
(*reverse)[index++] = buffer[i++];
(*reverse)[index++] = ' ';
wordEnd = wordStart - 1;
}
wordStart--;
}
for (int i = 0; i <= wordEnd; i++)
{
(*reverse)[index] = buffer[i];
index++;
}
if (!lastLine)
(*reverse)[index++] = '\n';
(*reverse)[index] = '\0';
}
1条答案
按热度按时间xlpyo6sf1#
***其中一个***问题是在
readLine
中,您像这样分配和复制字符串(代码缩短为相关部分):这将 * 不 * 为空值终止符分配空间。并且您将写入空值终止符 * 超出 * 分配的内存。这将导致 * 未定义的行为 *。
您需要为空终止符分配一个额外的字节:
[Note I don't cast the result,不要使用
sizeof(char)
,因为它被指定为 * 始终 * 等于1
。]***另一个***问题是,由于您没有在
bufferSize
中包含空终止符,因此main
中reverse
的分配也将是错误的:当然应该改为: