Speicherzugriffsfehler

sohalt
Hi!

Ich habe ein Programm geschrieben, und bei jedem aufruf gibt es allerhand zerheckselten Müll, sowie "Speicherzugriffsfehler" aus. Ich hoffe, das mir jmd. von euch helfen kann.
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
#include "fsbench.hh"

double write_block(FILE *pFile);
double write_char(FILE *pFile);
double write_random(FILE *pFile);
double read_block(FILE *pFile);
double read_char(FILE *pFile);
double read_random(FILE *pFile);

void startbench(char *file) {
	FILE *pFile;
	pFile = fopen(file, "w+");
	if(pFile == NULL) {
		fprintf(stderr, gettext("Unable to open file: %s\n"
		                        "NOTICE: You must have read and write permissions!\n"), file);
		exit(EXIT_FAILURE);
	}

	srand(time(NULL));

	printf(gettext("Write (per block) : %i Kb/sec\n"), write_block(pFile));
	printf(gettext("Write (per char)  : %i Kb/sec\n"), write_char(pFile));
	printf(gettext("Write (random)    : %i Kb/sec\n"), write_random(pFile));
	printf(gettext("Read (per block)  : %i Kb/sec\n"), read_block(pFile));
	printf(gettext("Read (per char)   : %i Kb/sec\n"), read_char(pFile));
	printf(gettext("Read (random)     : %i Kb/sec\n"), read_random(pFile));

	fclose(pFile);

	remove(file);
}

double write_block(FILE *pFile) {
	char block[5242880];
	for(int i = 0; i <= 5242880; i++) { block[i] = rand() % 255; }

	time_t start, end;
	time(&start);

	for(short i = 0; i <= 100; i++) { fputs(block, pFile); }

	time(&end);

	return(difftime(end, start) / 5120);
}

double write_char(FILE *pFile) {

}

double write_random(FILE *pFile) {

}

double read_block(FILE *pFile) {

}

double read_char(FILE *pFile) {

}

double read_random(FILE *pFile) {

}
die fsbench.hh
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <locale.h>
#include <libintl.h>
void usage();
void version();
void startbench(char *file);
die fsbench.cc (von der wird aufgerufen)
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
#include "fsbench.hh"

int main(int argc, char **argv) {
	setlocale(LC_ALL, "");
	bindtextdomain("fsbench", "/usr/share/locale");
	textdomain("fsbench");

	if(argc == 1) usage();
	while(argc--) {
		char *par = *argv++;
		if(!strcmp(par, "--usage") || !strcmp(par, "--help") || !strcmp(par, "-h")) usage();
		else if(!strcmp(par, "--version") || !strcmp(par, "-v")) version();
		else if(!strcmp(par, "--bench") || !strcmp(par, "-b")) { par = *argv++; startbench(par); }
	}

	return 0;
}
(sorry, wenn ich jetzt ein bisschen zuviel gepostet habe, ich denke zuviel ist besser als zu wenig.)

Wenn ich die Anwendung mit "fbench -b testfile" ausführe, kommt
code:
1:
2:
3:
4:
5:
6:
7:
te (per block) : 0 Kb/sec
te (per char)  : 134538656 Kb/sec
te (random)    : 134538656 Kb/sec
d (per block)  : 134538656 Kb/sec
d (per char)   : 134538656 Kb/sec
d (random)     : 134538656 Kb/sec
Speicherzugriffsfehler
mit exitcode 139. Die Datei "testfile" existiert nicht.

Woran liegt das, und wie behebe ich dieses Problem?

Danke!

PS: Kompillieren und Linken läuft komplett fehlerfrei.
Saemon
code:
1:
2:
3:
4:
char block[5242880];
for(int i = 0; i <= 5242880; i++) { block[i] = rand() % 255; }


kann es sein, dass du hier < verwenden müsstest? die zählung in arrays beginnt ja bei 0.
sohalt
Zitat:
Original von Saemon
code:
1:
2:
3:
4:
char block[5242880];
for(int i = 0; i <= 5242880; i++) { block[i] = rand() % 255; }


kann es sein, dass du hier < verwenden müsstest? die zählung in arrays beginnt ja bei 0.
Meinst du, stattdessen das hier?
code:
1:
2:
char block[5242880];
for(int i = 0; i < 5242880; i++) { block[i] = rand() % 255; }
Wenn ja: "Speicherzugriffsfehler" kommt immernoch, er gibt aber das aus, was er ausgeben soll, nur das Programm läuft nicht (write_block scheint 0 zurückzugeben, und tut eigentlich nichts).

Trozdem schonmal danke für deine (versuchte) Hilfe.
ThiefMaster
Lass es mal in einem Debugger (z.B. gdb oder valgrind) laufen und schau, wo genau der Fehler auftritt.
sohalt
Valgrind gefiel das mit dem
code:
1:
for(int i = 0; i < 5242880; i++) { block[i] = rand() % 255; }
nicht, dann habe ich 5242880 durch 32768 ersetzt, jetzt bringt er wenigstens da keinen Fehler mehr.
Einen fehler bringt er noch bei
code:
1:
if(!strcmp(par, "--usage") || !strcmp(par, "--help") || !strcmp(par, "-h")) usage();
"Invalid read of size 1" - was er auch immer damit meint...

"Speicherfehler" sagt er trozdem, und die angegebene Datei existiert nicht.

Trozdem erstmal danke Augenzwinkern
ThiefMaster
Ein int kann auch max. 32768 (bzw. 65536 wenn er unsigned ist) enthalten.
Für deine Zahl brauchst du schon einen long.
Und lass valgrind mal mit --leak-check=full laufen und poste die Ausgabe davon.
sohalt
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
==2210== Memcheck, a memory error detector.
==2210== Copyright (C) 2002-2005, and GNU GPL'd, by Julian Seward et al.
==2210== Using LibVEX rev 1471, a library for dynamic binary translation.
==2210== Copyright (C) 2004-2005, and GNU GPL'd, by OpenWorks LLP.
==2210== Using valgrind-3.1.0, a dynamic binary instrumentation framework.
==2210== Copyright (C) 2000-2005, and GNU GPL'd, by Julian Seward et al.
==2210== For more details, rerun with: -v
==2210==
==2210== Invalid read of size 1
==2210==    at 0x401D8F0: strcmp (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2210==    by 0x804887A: main (fsbench.cc:34)
==2210==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2210==
==2210== Process terminating with default action of signal 11 (SIGSEGV)
==2210==  Access not within mapped region at address 0x0
==2210==    at 0x401D8F0: strcmp (in /usr/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==2210==    by 0x804887A: main (fsbench.cc:34)
Write (per block) : 0 Kb/sec
Write (per char)  : 0 Kb/sec
Write (random)    : 0 Kb/sec
Read (per block)  : 0 Kb/sec
Read (per char)   : 0 Kb/sec
Read (random)     : 0 Kb/sec
==2210==
==2210== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 19 from 1)
==2210== malloc/free: in use at exit: 0 bytes in 0 blocks.
==2210== malloc/free: 451 allocs, 451 frees, 21,313 bytes allocated.
==2210== For counts of detected errors, rerun with: -v
==2210== No malloc'd blocks -- no leaks are possible.
in der fsbench.cc ist die 34. Zeile die 2. von denen:
code:
1:
2:
3:
                char *par = *argv++;
                if(!strcmp(par, "--usage") || !strcmp(par, "--help") || !strcmp(par, "-h")) usage();
                else if(!strcmp(par, "--version") || !strcmp(par, "-v")) version()
ThiefMaster
code:
1:
char *par = *argv++;
Das kann ja auch nicht gehen.
*charptr gibt dir grundsätzlich das erste Zeichen zurück, da *x == x[0] ist.
char *par = argv++; würde eher gehen - allerdings würde ich nicht argv selbst "versauen".
sohalt
Aber wie kommt es, dass der dann trozdem die entsprechende Funktion aufruft? (Sonst würde der den kram ja nicht anzeigen). Oder meinst du jetzt, dass das mit dem Speicherfehler zusammenhängt? Und wenn ich das ändere, meint der compiler:
code:
1:
2:
fsbench.cc: In function `int main(int, char**)':
fsbench.cc:33: error: cannot convert `char**' to `char*' in initialization
Das kann es also nicht so ganz sein.

Trozdem bedank ich mich für deinen Versuch. Augenzwinkern
ThiefMaster
Versuch mal das: char *par = argv[argc-1];

Ansonsten schau dir mal die Systemfunktion getopt() bzw. getopt_long() an, falls du unter Linux o.ä. entwickelst.
sohalt
Ne, also dann kommt er mit "Bus-Zugriffsfehler". Ich probier jetzt mal, das, wie du vorschlägst, mit getopt() zu realisieren.
sohalt
Ich habe das jetzt mit getopt() realisiert. Der Speicherzugriffsfehler ist weg, aber die funktion startbench, bzw. write_block funktioniert immernoch nicht.