14 Replies - 5271 Views - Last Post: 01 December 2010 - 10:01 AM Rate Topic: -----

#1 Allizoid  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 91
  • Joined: 09-November 09

Dynamic array/struct

Posted 30 November 2010 - 08:39 AM

Hey,

I'm getting the below error message:

GraphClient.c: In function ‘main’:
GraphClient.c:11: error: invalid application of ‘sizeof’ to incomplete type ‘struct Edge’
GraphClient.c:11: error: invalid initializer

Been playing around with graphs for a few weeks, and I've become notorious for this kind of error, but when I seek help my error is just corrected for me and I never understand why. Could someone please explain to me what is happening, and how to fix it, and why (or point me in the right direction)?


//GraphClient.c
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"

int main (int argc, char *argv[]) {	
	int numVert = 0;
	printf ("Enter number of vertices: ");
	scanf ("%d", &numVert);

	Edge e[] = malloc(sizeof(struct Edge) * numVert);
	Graph new = newGraph(numVert);
	
	int cnt = 0;
	while (cnt < numVert) {
		scanf("%d-%d", &e[cnt].v,&e[cnt].w);
		insertE(new, e[cnt]);
		cnt++;
	}
	
	show(new);
	return 0;
}


//Graph.h
typedef int Vertex;         
typedef struct { 
    Vertex v;
    Vertex w;
} Edge;                       

Edge mkEdge(Vertex a, Vertex B)/>;

typedef struct graphRep *Graph;

Graph newGraph (int nV);          
void  insertE(Graph g, Edge e);   
void  removeE(Graph g, Edge e);   
int   edges(Edge e[], Graph g); 
Graph copy(Graph g);    
void  destroy(Graph g);         
void  show(Graph g);            




I've excluded Graph.c, as I didn't think it was relevant.
Any help is appreciated :)

This post has been edited by Allizoid: 30 November 2010 - 08:40 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Dynamic array/struct

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,548
  • Joined: 23-August 08

Re: Dynamic array/struct

Posted 30 November 2010 - 09:08 AM

I think you're looking for sizeof(Edge). There is no struct Edge in your code; you've typedef'd an anonymous struct as a type called Edge.
Was This Post Helpful? 1
  • +
  • -

#3 Allizoid  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 91
  • Joined: 09-November 09

Re: Dynamic array/struct

Posted 30 November 2010 - 09:39 PM

Thanks for the reply, and apologies for leaving the thread overnight.

I initially tried your solution, but it yields a similar error:

GraphClient.c: In function ‘main’:
GraphClient.c:11: error: invalid initializer
Was This Post Helpful? 0
  • +
  • -

#4 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Dynamic array/struct

Posted 30 November 2010 - 10:03 PM

malloc returns a pointer to the memory block that it is allocating. You have to cast it to the type that is appropriate for the data you will store there, and assign it to the corresponding type of pointer. In this case:

    Edge *e = (Edge*)malloc(sizeof(Edge) * numVert);



Now e is a pointer to the first Edge in the array.
Was This Post Helpful? 1
  • +
  • -

#5 Allizoid  Icon User is offline

  • D.I.C Head

Reputation: 4
  • View blog
  • Posts: 91
  • Joined: 09-November 09

Re: Dynamic array/struct

Posted 30 November 2010 - 10:29 PM

View Postr.stiltskin, on 30 November 2010 - 09:03 PM, said:

malloc returns a pointer to the memory block that it is allocating. You have to cast it to the type that is appropriate for the data you will store there, and assign it to the corresponding type of pointer. In this case:

    Edge *e = (Edge*)malloc(sizeof(Edge) * numVert);



Now e is a pointer to the first Edge in the array.


Thanks, I think I get it now.
Just a few questions though.. Would it be fine to cast everything I malloc? I've always been taught to cast 2d arrays, but not 1d arrays... Why?
//2d array
int **array = (int **) malloc (length * sizeof(int*));
assert (array != NULL);

for (i = 0; i < length; i++) {
   array[i] = (int *) malloc (length * sizeof(int));
   assert(array[i] != NULL);
}



//1d array
int *array = malloc(length * sizeof(int));
assert (array != NULL);


This post has been edited by Allizoid: 30 November 2010 - 10:30 PM

Was This Post Helpful? 0
  • +
  • -

#6 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Dynamic array/struct

Posted 30 November 2010 - 10:51 PM

View PostAllizoid, on 01 December 2010 - 12:29 AM, said:

Would it be fine to cast everything I malloc? I've always been taught to cast 2d arrays, but not 1d arrays... Why?

You've been taught NOT to cast when allocating 1d arrays? I can't imagine why. So what have you been taught to write for 1d arrays?
Was This Post Helpful? 0
  • +
  • -

#7 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Dynamic array/struct

Posted 01 December 2010 - 05:10 AM

In C it's considered bad form to cast malloc. Some people still prefer to, but if you do you should be consistent about it. Casting for one type and not for another reeks of bad code.

Of course, C++ demands you cast void *, but you really shouldn't be using malloc in C++ anyway.
Was This Post Helpful? 2
  • +
  • -

#8 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: Dynamic array/struct

Posted 01 December 2010 - 06:03 AM

Casting malloc (in C) is bad. There's no doubt. It's not syntactically necessary in C. So you get 0 positive benefits. On the other hand, if you made a mistake, the cast will silence the mistake. You'll shift a mistake catcheable at compile time to run time. That's really bad.

So no upsides, potential big downsides. Who likes this?
Was This Post Helpful? 4
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Dynamic array/struct

Posted 01 December 2010 - 08:05 AM

Basically, C++ programmers and old C programmers who apparently didn't get the void pointer memo. :P
Was This Post Helpful? 0
  • +
  • -

#10 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Dynamic array/struct

Posted 01 December 2010 - 08:11 AM

That's very surprising. This is the first time I've heard anybody complain about casting malloc and I think I've done it ever since I first learned C. So where did I get the idea to do that in the first place: K&R. On page 142 of The C Programming Language, 2nd Edition:

Kernighan and Ritchie said:

The question of the type declaration for a function like malloc is a vexing one for any language that takes type-checking seriously. In C, the proper method is to declare that malloc returns a pointer to void, then explicitly coerce the pointer into the desired type with a cast.

I don't mean to argue, but I would like to know when and why that changed. And if malloc really shouldn't be cast, the bad news is that DIC's TUTORIALS are rife with examples of explicitly casting it:

One, two, three, four, five, six, seven, eight, nine, ten, eleven.

That's virtually every C tutorial on the site that uses malloc. Hmmm...

This post has been edited by r.stiltskin: 01 December 2010 - 08:16 AM

Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Dynamic array/struct

Posted 01 December 2010 - 08:37 AM

You're dealing with old information and habits. It logical to avoid casting warnings away; some people have just been doing it for too long.

As to K&R:

K&R Errata said:

142(§6.5, toward the end): The remark about casting the return value of malloc ("the proper method is to declare ... then explicitly coerce") needs to be rewritten. The example is correct and works, but the advice is debatable in the context of the 1988-1989 ANSI/ISO standards. It's not necessary (given that coercion of void * to ALMOSTANYTYPE * is automatic), and possibly harmful if malloc, or a proxy for it, fails to be declared as returning void *. The explicit cast can cover up an unintended error. On the other hand, pre-ANSI, the cast was necessary, and it is in C++ also.

-- Errata for The C Programming Language, Second Edition
-- http://cm.bell-labs....ok/2ediffs.html

Was This Post Helpful? 3
  • +
  • -

#12 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Dynamic array/struct

Posted 01 December 2010 - 09:11 AM

Good to know. Thanks. But then those tutorials should be cleaned up.
Was This Post Helpful? 0
  • +
  • -

#13 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5882
  • View blog
  • Posts: 12,761
  • Joined: 16-October 07

Re: Dynamic array/struct

Posted 01 December 2010 - 09:46 AM

People still use goto. And globals. And... name your poison. It's not "wrong" because it works. If it works, you'll always be able to find a programmer to tell you why it's the best possible way to do it.

Casting malloc isn't wrong; you're allowed to do it. Just, given all the information, why would you? It's certainly not a best practice. In the past I've cast voids and used many globals; you live and learn.
Was This Post Helpful? 0
  • +
  • -

#14 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Dynamic array/struct

Posted 01 December 2010 - 10:01 AM

I totally agree. I'm just saying that the people who are learning from the tutorials probably aren't reading this discussion. DIC shouldn't be teaching "(un)necessary ... and possibly harmful" coding practices. Why get new programmers into bad habits that they'll have to unlearn?

This post has been edited by r.stiltskin: 01 December 2010 - 10:05 AM

Was This Post Helpful? 0
  • +
  • -

#15 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6078
  • View blog
  • Posts: 23,548
  • Joined: 23-August 08

Re: Dynamic array/struct

Posted 01 December 2010 - 10:01 AM

View Postr.stiltskin, on 01 December 2010 - 10:11 AM, said:

Good to know. Thanks. But then those tutorials should be cleaned up.


All fixed.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1