Утечка памяти в программе, которая считывает и выводит строку - C (СИ)
Формулировка задачи:
Есть вот такая простая программа, считывающая строку с клавиатуры и выводящая ее.
Программа рабочая, но valgrind находит утечку, хотя все освобождено
Программа (не эта, но с аналогичной проблемой, просто более громоздкая) должна пройти тестирование в специальной системе, так что просто забыть о проблеме не вариант
Заранее спасибо за любые советы
#include <stdio.h>
#include <stdlib.h>
int main(){
char* string =(char*)malloc(50*sizeof(char));
int i = 0,
N = 0;
while((string[i] = getchar()) != EOF) {
if(string[i] == '\n') N++;
i++;
}
printf("%s\n", string);
free(string);
return 0;
}Решение задачи: «Утечка памяти в программе, которая считывает и выводит строку»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void LowerRegister(char** pStrings,int NN,char** pNewStrings)
{
if (!NN)
{
return;
}
for (int ii = 0; ii < NN; ++ii)
{
for (int jj = 0; true; ++jj)
{
int iChr = pStrings[ii][jj];
if (iChr)
{
pNewStrings[ii][jj] = (char)(((iChr >= 'A') && (iChr <= 'Z')) ? iChr | 0x20 : iChr);
}
else
{
break;
}
}
}
}
int main(int argc,char** argv)
{
const int MAX_STRING = 5;
const int MAX_LENGTH = 5;
char** pStrings = (char**)malloc(sizeof(char*) * MAX_STRING);
if (!pStrings)
{
printf("\nErr: Memory error.\n");
return 0;
}
memset(pStrings,0,sizeof(char*) * MAX_STRING);
int ii = 0;
int jj = 0;
for (ii = 0; ii < MAX_STRING; ++ii)
{
pStrings[ii] = (char*)malloc(MAX_LENGTH + 1);
if (pStrings[ii])
{
memset(pStrings[ii],0,MAX_LENGTH + 1);
}
else
{
for (jj = 0; jj < ii; ++jj)
{
if (pStrings && pStrings[jj])
{
free(pStrings[jj]);
pStrings[jj] = NULL;
}
}
if (pStrings)
{
free(pStrings);
pStrings = NULL;
}
printf("\nErr: Memory error.\n");
return 0;
}
}
char** pNewStrings = (char**)malloc(sizeof(char*) * MAX_STRING);
if (!pNewStrings)
{
printf("\nErr: Memory error.\n");
return 0;
}
memset(pNewStrings,0,sizeof(char*) * MAX_STRING);
for (ii = 0; ii < MAX_STRING; ++ii)
{
pNewStrings[ii] = (char*)malloc(MAX_LENGTH + 1);
if (pNewStrings[ii])
{
memset(pNewStrings[ii],0,MAX_LENGTH + 1);
}
else
{
for (int jj = 0; jj < MAX_STRING; ++jj)
{
if (pStrings && pStrings[jj])
{
free(pStrings[jj]);
pStrings[jj] = NULL;
}
}
if (pStrings)
{
free(pStrings);
pStrings = NULL;
}
for (jj = 0; jj < ii; ++jj)
{
if (pNewStrings && pNewStrings[jj])
{
free(pNewStrings[jj]);
pNewStrings[jj] = NULL;
}
}
if (pNewStrings)
{
free(pNewStrings);
pNewStrings = NULL;
}
printf("\nErr: Memory error.\n");
return 0;
}
}
ii = 0;
jj = 0;
int NN = 0;
int iChr = 0;
while ((iChr = getchar()) != EOF)
{
if (iChr == '\n')
{
jj = 0;
++ii;
++NN;
if (ii > MAX_STRING)
{
for (ii = 0; ii < MAX_STRING; ++ii)
{
if (pStrings && pStrings[ii])
{
free(pStrings[ii]);
pStrings[ii] = NULL;
}
if (pNewStrings && pNewStrings[ii])
{
free(pNewStrings[ii]);
pNewStrings[ii] = NULL;
}
}
if (pStrings)
{
free(pStrings);
pStrings = NULL;
}
if (pNewStrings)
{
free(pNewStrings);
pStrings = NULL;
}
printf("\nErr: Too many strings.\n");
return 0;
}
}
else if (jj > (MAX_LENGTH + 1))
{
for (ii = 0; ii < MAX_STRING; ++ii)
{
if (pStrings && pStrings[ii])
{
free(pStrings[ii]);
pStrings[ii] = NULL;
}
if (pNewStrings && pNewStrings[ii])
{
free(pNewStrings[ii]);
pStrings = NULL;
}
}
if (pStrings)
{
free(pStrings);
pStrings = NULL;
}
if (pNewStrings)
{
free(pNewStrings);
pNewStrings = NULL;
}
printf("\nErr: Too many symbols in the string.\n");
return 0;
}
else
{
pStrings[ii][jj++] = (char)iChr;
pStrings[ii][jj] = 0; // Ensure ASCIIZ
}
}
LowerRegister(pStrings,NN,pNewStrings);
for (ii = 0; ii < NN; ++ii)
{
printf("%s\n",pNewStrings[ii]);
}
for (ii = 0; ii < MAX_STRING; ++ii)
{
if (pStrings && pStrings[ii])
{
free(pStrings[ii]);
pStrings[ii] = NULL;
}
if (pNewStrings && pNewStrings[ii])
{
free(pNewStrings[ii]);
pNewStrings[ii] = NULL;
}
}
if (pStrings)
{
free(pStrings);
pStrings = NULL;
}
if (pNewStrings)
{
free(pNewStrings);
pNewStrings = NULL;
}
return 0;
}
Объяснение кода листинга программы
Этот код считывает строки из стандартного ввода до тех пор, пока не будет введено что-то, что не является символом строки. Затем он преобразует каждую строку в нижний регистр. Если вводится больше строк, чем есть в массиве, код выведет сообщение об ошибке и завершит работу. Если вводится строка, которая превышает максимально допустимую длину, код также выведет сообщение об ошибке и завершит работу. Код использует динамическое выделение памяти для хранения вводимых строк и преобразованных строк.