PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Struktur an Funktion übergeben



jay-t
30-12-2011, 21:21
Ich versuche einen Pointer auf eine Struktur an eine Funktion zu übergeben, da stimmt irgendwas nicht:



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

typedef unsigned char U1; /* UBYTE */
typedef signed short S2; /* INT */
typedef unsigned short U2; /* UINT */
typedef signed int S4; /* LONGINT */
typedef double F8; /* DOUBLE */

struct varlist
{
U1 type; /* type of variable */
U1 name[100]; /* name */
U1 vm; /* virtual memory (BOOL) */
S4 vm_ind; /* start position in vm-file */
S4 vmcache_ind; /* cache index */
U1 vmcache_mod; /* cache modify flag: (0 = not modified, 1 = modified) */
S4 dims; /* -1 = NODIMS => no array */
S4 dimens[100];

S2 *i_m;
S4 *li_m;
F8 *d_m;
U1 *s_m;
S4 size;

S2 *i_vm;
S4 *li_vm;
F8 *d_vm;
U1 *s_vm;
S4 vmcachesize;
};

void init_varlist (struct varlist *varlist, S4 init_maxvarlist)
{
/* set all mem-pointers to NULL */

S4 i;

for (i = 0; i <= init_maxvarlist; i++)
{
varlist[i].i_m = NULL;
varlist[i].li_m = NULL;
varlist[i].d_m = NULL;
varlist[i].s_m = NULL;
varlist[i].i_vm = NULL;
varlist[i].li_vm = NULL;
varlist[i].d_vm = NULL;
varlist[i].s_vm = NULL;
varlist[i].size = 0;
varlist[i].dims = 0;
varlist[i].vm = 0;
varlist[i].type = 0;
strcpy (varlist[i].name, "");
}
}

int main ()
{
struct varlist *varlist;

varlist = (struct varlist *) malloc (100 * sizeof (struct varlist));
if (varlist == NULL)
{
printf ("error allocating varlist!\n");
exit (1);
}

init_varlist ((struct varlist *) &varlist, 99);
free (varlist);
}


Die Ausgabe von Valgrind:



==4193== Command: ./varlist
==4193==
==4193== Invalid write of size 8
==4193== at 0x40063F: init_varlist (varlist.c:44)
==4193== by 0x4007DD: main (varlist.c:71)
==4193== Address 0x7ff001208 is not stack'd, malloc'd or (recently) free'd


Was ist in der Funktion init_varlist falsch? Das ich die mit dem Argument &varlist aufrufen muss, stimmt doch oder?

sommerfee
30-12-2011, 21:44
Das ich die mit dem Argument &varlist aufrufen muss, stimmt doch oder?

Nein.
init_varlist (varlist, 99); wäre richtig.

jeebee
30-12-2011, 23:50
noch zu deinen integer typedefs: die erhältst du (ab C99, afair) mit
#include <stdint.h> als
uint8_t //typedef unsigned char U1; /* UBYTE */
int16_t //typedef signed short S2; /* INT */
uint16_t //typedef unsigned short U2; /* UINT */
int32_t //typedef signed int S4; /* LONGINT */

und den Pointer den du von malloc zurück erhältst musst du auch nicht explizit casten.

jay-t
31-12-2011, 17:12
Danke für eure Tipps!

Bei z.B. uint8_t: was ist da der Unterschied zu "unsigned char".
Sind das einfach neuere Bezeichnungen?
Würde mich mal interessieren.

Das mit den typedefs mache ich nur deshalb, weil das Programm aus dem ich
die Funktionen habe, auf mehreren Plattformen laufen soll.

Damit die Typen genau festgelegt sind.

jeebee
01-01-2012, 14:16
[u]int_{8,16,32,64}_t sind Datentypen die in C99 eingeführt wurden, da der originale C-Standard keine Garantien bezüglich der Anzahl Bits der Basistypen machte. Zum Beispiel definiert der C-Standard 'int' als Ganzzahlentyp mit Anzahl Bits gleich der grundlegenden Anzahl Bits der CPU-Architektur (dies stimmt heute auch nicht mehr unbedingt, so ist 'int' auf Intel/AMD 64bit Architekturen immer noch 32bit).

[u]int_{8,16,32,64} sind Datentypen die immer die spezifizierte Anzahl Bits (8, 16, 32, 64) haben, egal auf welcher CPU-Architektur.