大小读取无效 - C valgrind
Invalid read of size - C valgrind
int main(int argc, char **argv) {
if (argc < 3) {
printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
printf("Beispiel: %s 100 Bayern\n", argv[0]);
printf("Klein-/Großschreibung beachten!\n");
exit(1);
}
int anzahl = atoi(argv[1]);
char *bundesland = argv[2];
// Statisch allokierter Speicher
char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
int bewohner[MAX_LAENGE_ARR];
int len = read_file("staedte.csv", staedte, laender, bewohner);
// Hier implementieren
int x=0;
int d=0;
//int b=0;
//char* zeile_array=(char*) malloc (len * sizeof(char));
char *zeile_array[50];
char *zeile;
zeile=(char*) malloc(100); //allocating memory
for(x=0;x<len;x++)
{
if(strcmp(laender[x],bundesland) == 0 && bewohner[x] >= anzahl)
{
sprintf(zeile, "Die Stadt %p hat %d Einwohner.",staedte[x],bewohner[x]);
zeile_array[d]=zeile; // putting it into array
d=d+1;
}
}
//b++;
}
write_file(zeile_array,d);
free(zeile);
}
input3.c :
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "input3.h"
int MAX_LAENGE_STR = 255;
int MAX_LAENGE_ARR = 100;
void write_file(char *result[], int len) {
FILE *fp = fopen("resultat.txt", "w");
if (fp == NULL){
perror("resultat.txt");
exit(1);
}
for (int i=0; i<len; i++) {
fprintf(fp, "%s\n", result[i]);
}
fclose(fp);
}
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char laender[][MAX_LAENGE_STR], int bewohner []) {
FILE *fp = fopen(dateiname, "r");
if (fp == NULL){
perror(dateiname);
exit(1);
}
char stadt[MAX_LAENGE_STR];
char land[MAX_LAENGE_STR];
int anzahl;
int i = 0;
int len;
while(fscanf(fp, "\"%[^\"]\";\"%[^\"]\";%d\n", stadt, land, &anzahl) != EOF)
{
if (i >= MAX_LAENGE_ARR) {
printf("ERROR: Die Datei ist größer als erwartet!");
return i;
}
len = strlen(land) + 1;
strncpy(laender[i], land, len-1);
laender[i][len-1] = '[=11=]';
len = strlen(stadt) + 1;
strncpy(staedte[i], stadt, len-1);
staedte[i][len-1] = '[=11=]';
bewohner[i] = anzahl;
i++;
}
fclose(fp);
return i;
}
input3.h:
extern int MAX_LAENGE_ARR;
extern int MAX_LAENGE_STR;
void write_file(char *result[], int len);
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char `laender[][MAX_LAENGE_STR], int bewohner []);
`
Invalid read of size 2
==23056== at 0x4EC361B: __GI_mempcpy (memcpy.S:83)
==23056== by 0x4EB054C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1320)
==23056== by 0x4E82904: vfprintf (vfprintf.c:1661)
==23056== by 0x4E8B336: fprintf (fprintf.c:32)
==23056== by 0x400EE0: write_file (input3.c:17)
==23056== by 0x400E52: main (d.c:56)
==23056== Address 0x51fc391 is 33 bytes inside a block of size 100 free'd
==23056== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so)
==23056== by 0x400E14: main (d.c:50)
staedte.csv 的前 4 行:
"Berlin";"Berlin";3460725
"Hamburg";"Hamburg";1786448
"München";"Bayern";1353186
"Köln";"Nordrhein-Westfalen";1007119
"Frankfurt am Main";"Hessen";679664
我只是想将一些字符串写入一个新文件,但我每次都遇到相同的内存错误。
我情不自禁
我需要帮助来解决这个错误。
我不知道如何修复它,我很绝望。
下面是 main()
中提出的解决方案:
更正的错误和改进列表:
1- 在格式化输出中,将 %p
(专用于指针)替换为 %s
(专用于字符串)。
2- 在存储到输出字符串之前 zeile_array[d]
将其分配给输出文本的长度 zeile
包括空终止符。
3- 不是将输出文本指针 zeile
复制到输出字符串 zeile_array[d]
,而是使用 strcpy()
函数移动所有字符。
4- 为简化,修改临时字符串 zeile
从 char 指针动态分配在内存中,通过在堆栈中自动分配的简单 char 数组。
5-为了保护,当数组char *zeile_array[50];
的所有项都被使用时停止结果的提取。或者简单地使用 MAX_LAENGE_ARR
constante.
分配足够的数组
// Hier implementieren
int x=0;
int d=0;
//int b=0;
//char* zeile_array=(char*) malloc (len * sizeof(char));
char *zeile_array[MAX_LAENGE_ARR]; // instead of char *zeile_array[50];
char zeile[100];
// zeile=(char*) malloc(100); // allocated memory not needed
for(x=0;x<len;x++)
{
if(strcmp(laender[x],bundesland) == 0 && bewohner[x] >= anzahl)
{
// as Micheal Walz said, replace %p by %s
sprintf(zeile, "Die Stadt %s hat %d Einwohner.",staedte[x],bewohner[x]);
// allocate the storing item
zeile_array[d]=(char *)malloc(strlen(zeile)+1);
// copy the formatted text into the storing item
strcpy(zeile_array[d],zeile); // putting it into array
d=d+1;
// abort research when output array is full
if (d >= MAX_LAENGE_ARR) break;
}
}
//b++;
//} // remove unexpected end of block
write_file(zeile_array,d);
// free the allocated memory only
for(x=0;x<d;x++)
{
free(zeile_array[x]);
}
// free(zeile); is no more needed
int main(int argc, char **argv) {
if (argc < 3) {
printf("Aufruf: %s <anzahl> <bundesland>\n", argv[0]);
printf("Beispiel: %s 100 Bayern\n", argv[0]);
printf("Klein-/Großschreibung beachten!\n");
exit(1);
}
int anzahl = atoi(argv[1]);
char *bundesland = argv[2];
// Statisch allokierter Speicher
char staedte[MAX_LAENGE_ARR][MAX_LAENGE_STR];
char laender[MAX_LAENGE_ARR][MAX_LAENGE_STR];
int bewohner[MAX_LAENGE_ARR];
int len = read_file("staedte.csv", staedte, laender, bewohner);
// Hier implementieren
int x=0;
int d=0;
//int b=0;
//char* zeile_array=(char*) malloc (len * sizeof(char));
char *zeile_array[50];
char *zeile;
zeile=(char*) malloc(100); //allocating memory
for(x=0;x<len;x++)
{
if(strcmp(laender[x],bundesland) == 0 && bewohner[x] >= anzahl)
{
sprintf(zeile, "Die Stadt %p hat %d Einwohner.",staedte[x],bewohner[x]);
zeile_array[d]=zeile; // putting it into array
d=d+1;
}
}
//b++;
}
write_file(zeile_array,d);
free(zeile);
}
input3.c :
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "input3.h"
int MAX_LAENGE_STR = 255;
int MAX_LAENGE_ARR = 100;
void write_file(char *result[], int len) {
FILE *fp = fopen("resultat.txt", "w");
if (fp == NULL){
perror("resultat.txt");
exit(1);
}
for (int i=0; i<len; i++) {
fprintf(fp, "%s\n", result[i]);
}
fclose(fp);
}
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char laender[][MAX_LAENGE_STR], int bewohner []) {
FILE *fp = fopen(dateiname, "r");
if (fp == NULL){
perror(dateiname);
exit(1);
}
char stadt[MAX_LAENGE_STR];
char land[MAX_LAENGE_STR];
int anzahl;
int i = 0;
int len;
while(fscanf(fp, "\"%[^\"]\";\"%[^\"]\";%d\n", stadt, land, &anzahl) != EOF)
{
if (i >= MAX_LAENGE_ARR) {
printf("ERROR: Die Datei ist größer als erwartet!");
return i;
}
len = strlen(land) + 1;
strncpy(laender[i], land, len-1);
laender[i][len-1] = '[=11=]';
len = strlen(stadt) + 1;
strncpy(staedte[i], stadt, len-1);
staedte[i][len-1] = '[=11=]';
bewohner[i] = anzahl;
i++;
}
fclose(fp);
return i;
}
input3.h:
extern int MAX_LAENGE_ARR;
extern int MAX_LAENGE_STR;
void write_file(char *result[], int len);
int read_file(char *dateiname, char staedte[][MAX_LAENGE_STR], char `laender[][MAX_LAENGE_STR], int bewohner []);
`
Invalid read of size 2
==23056== at 0x4EC361B: __GI_mempcpy (memcpy.S:83)
==23056== by 0x4EB054C: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1320)
==23056== by 0x4E82904: vfprintf (vfprintf.c:1661)
==23056== by 0x4E8B336: fprintf (fprintf.c:32)
==23056== by 0x400EE0: write_file (input3.c:17)
==23056== by 0x400E52: main (d.c:56)
==23056== Address 0x51fc391 is 33 bytes inside a block of size 100 free'd
==23056== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck- amd64-linux.so)
==23056== by 0x400E14: main (d.c:50)
staedte.csv 的前 4 行:
"Berlin";"Berlin";3460725
"Hamburg";"Hamburg";1786448
"München";"Bayern";1353186
"Köln";"Nordrhein-Westfalen";1007119
"Frankfurt am Main";"Hessen";679664
我只是想将一些字符串写入一个新文件,但我每次都遇到相同的内存错误。 我情不自禁 我需要帮助来解决这个错误。 我不知道如何修复它,我很绝望。
下面是 main()
中提出的解决方案:
更正的错误和改进列表:
1- 在格式化输出中,将 %p
(专用于指针)替换为 %s
(专用于字符串)。
2- 在存储到输出字符串之前 zeile_array[d]
将其分配给输出文本的长度 zeile
包括空终止符。
3- 不是将输出文本指针 zeile
复制到输出字符串 zeile_array[d]
,而是使用 strcpy()
函数移动所有字符。
4- 为简化,修改临时字符串 zeile
从 char 指针动态分配在内存中,通过在堆栈中自动分配的简单 char 数组。
5-为了保护,当数组char *zeile_array[50];
的所有项都被使用时停止结果的提取。或者简单地使用 MAX_LAENGE_ARR
constante.
// Hier implementieren
int x=0;
int d=0;
//int b=0;
//char* zeile_array=(char*) malloc (len * sizeof(char));
char *zeile_array[MAX_LAENGE_ARR]; // instead of char *zeile_array[50];
char zeile[100];
// zeile=(char*) malloc(100); // allocated memory not needed
for(x=0;x<len;x++)
{
if(strcmp(laender[x],bundesland) == 0 && bewohner[x] >= anzahl)
{
// as Micheal Walz said, replace %p by %s
sprintf(zeile, "Die Stadt %s hat %d Einwohner.",staedte[x],bewohner[x]);
// allocate the storing item
zeile_array[d]=(char *)malloc(strlen(zeile)+1);
// copy the formatted text into the storing item
strcpy(zeile_array[d],zeile); // putting it into array
d=d+1;
// abort research when output array is full
if (d >= MAX_LAENGE_ARR) break;
}
}
//b++;
//} // remove unexpected end of block
write_file(zeile_array,d);
// free the allocated memory only
for(x=0;x<d;x++)
{
free(zeile_array[x]);
}
// free(zeile); is no more needed