Thread: Dynamic memory allocation for structs passed to function

  1. #1
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8

    Dynamic memory allocation for structs passed to function

    Hi,


    I have to make a program that acts as a spam filter, and part of the program has to dynamicly allocate memroy to a member of a struct that is passed to a function..
    But I'm doing it quite wrong..

    What I have is as follows..


    (PS this is FAR from complete, but as you can see I'm just doing the memory allocation completely wrong..)

    Code:
    typedef struct {
    	double weight;
    	char *word;
    } feature;
    
    typedef struct {
    	feature *features;
    	int size;
    } dictionary;
    
    void dictionary_read(dictionary *dict, const char *filename){
    	FILE* bestand;
    	double aantal; //aantal = amount in dutch
    	bestand = fopen(filename,"r");
    	fscanf(bestand,"%lf", &aantal);
    
    	dict->features = (dict->features)calloc(aantal,sizeof(dict->features));
    
    
    	fclose(bestand);
    }

    Kind regards.

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Code:
    	dict->features = (dict->features)calloc(aantal,sizeof(dict->features));
    Perhaps, you should read/learn C first before coding this up.
    You don't need to cast malloc/calloc/realloc in C. It's not recommended.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8
    Quote Originally Posted by Bayint Naung View Post
    Code:
    	dict->features = (dict->features)calloc(aantal,sizeof(dict->features));
    Perhaps, you should read/learn C first before coding this up.
    You don't need to cast malloc/calloc/realloc in C. It's not recommended.
    In our book it is used as follows:

    Code:
    int** a;
    
    a = (int**)calloc(5,sizeof(int*))
    I do know how to program in C, or I'm learning it, atleast..
    So instead of just criticizing my, clearly wrong attempt, you could perhaps guide me in the right direction?

    I've used the calloc/malloc functions only once before in a much simpler case for arrays, as follow:
    Code:
    tokens = (char**)calloc(*arraylength, sizeof(char*));
    and then in a loop again to allocate memory for every array of chars..

    which works perfectly...

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by eXcellion View Post
    In our book it is used as follows:

    Code:
    int** a;
    
    a = (int**)calloc(5,sizeof(int*))
    I do know how to program in C, or I'm learning it, atleast..
    So instead of just criticizing my, clearly wrong attempt, you could perhaps guide me in the right direction?
    I see this all the time and for C it's wrong... for C++ it's right. Be careful of this.
    Should be...
    Code:
    a = calloc(5,sizeof(int*));
    
    //or if allocating an int* instead of an int**
    
    a = calloc(5,sizeof(int));
    In C calloc(), malloc() and realloc() return void* which can be assigned to any pointer.

    For the actual problematic code line...
    Code:
    dict->features = (dict->features)calloc(aantal,sizeof(dict->features));
    
    // should be
    
    dict->featuers = calloc(aantal,sizeof(features));
    This because you are making space for the struct itself, not a pointer to the struct.

  5. #5
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8
    Quote Originally Posted by CommonTater View Post
    I see this all the time and for C it's wrong... for C++ it's right. Be careful of this.
    Should be...
    Code:
    a = calloc(5,sizeof(int*));
    
    //or if allocating an int* instead of an int**
    
    a = calloc(5,sizeof(int));
    In C calloc(), malloc() and realloc() return void* which can be assigned to any pointer.

    For the actual problematic code line...
    Code:
    dict->features = (dict->features)calloc(aantal,sizeof(dict->features));
    
    // should be
    
    dict->features = calloc(aantal,sizeof(feature));
    This because you are making space for the struct itself, not a pointer to the struct.
    But if I use the code you provided, without the cast, how ca it work? because as someone said, calloc indeed returns void, (and the compiler is complaining about the same thing.)

  6. #6
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    But if I use the code you provided, without the cast, how ca it work? because as someone said, calloc indeed returns void, (and the compiler is complaining about the same thing.)
    Did you include stdlib.h which has prototype of these functions?

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    If the compiler is complaining about calloc() returning a void * then you're not using a C compiler, you're using a C++ compiler.
    If you understand what you're doing, you're not learning anything.

  8. #8
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8
    Quote Originally Posted by Bayint Naung View Post
    Did you include stdlib.h which has prototype of these functions?
    Yes.

    Code:
    #include <stdio.h>
    #include "stringutilities.h"
    #include "dictionary.h"
    #include <stdlib.h>
    is at the top

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by itsme86 View Post
    If the compiler is complaining about calloc() returning a void * then you're not using a C compiler, you're using a C++ compiler.
    Exactly...

  10. #10
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I wish the casting of malloc didn't keep coming up. "Not recommended" is just for people who don't know enough to include the recommended #include file. Their loss

    Even for compilers who don't mind casting (void *) themselves without warnings there is nothing wrong with doing an explicit cast. It lets the next reader know that the return type pointer is compatible with what was intended. Yes, C++ compiler will issue warnings if not explicitly cast while C does not. Or, as has been pointed out to me in the past, because I use ".cpp" extension on my source code, this happens. Personally I don't mind the compiler reminding me that an explicit cast is a good idea. I like to compile without warnings at the highest pedantic level.

  11. #11
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8
    Quote Originally Posted by nonoob View Post
    I wish the casting of malloc didn't keep coming up. "Not recommended" is just for people who don't know enough to include the recommended #include file. Their loss

    Even for compilers who don't mind casting (void *) themselves without warnings there is nothing wrong with doing an explicit cast. It lets the next reader know that the return type pointer is compatible with what was intended. Yes, C++ compiler will issue warnings if not explicitly cast while C does not. Or, as has been pointed out to me in the past, because I use ".cpp" extension on my source code, this happens. Personally I don't mind the compiler reminding me that an explicit cast is a good idea. I like to compile without warnings at the highest pedantic level.
    Yes, I am using Visual Studio's C++ compiler (using .c) files..
    We have to use that compiler from uni...

    So..

    Code:
    dict->features = calloc(aantal,sizeof(feature));
    When casting, becomes..

    Code:
    dict->features = (...)calloc(aantal,sizeof(feature));
    I know it needs to be one level higher then the type 'feature') but I'm not sure 'how'

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by nonoob View Post
    I wish the casting of malloc didn't keep coming up. "Not recommended" is just for people who don't know enough to include the recommended #include file. Their loss

    Even for compilers who don't mind casting (void *) themselves without warnings there is nothing wrong with doing an explicit cast. It lets the next reader know that the return type pointer is compatible with what was intended. Yes, C++ compiler will issue warnings if not explicitly cast while C does not. Or, as has been pointed out to me in the past, because I use ".cpp" extension on my source code, this happens. Personally I don't mind the compiler reminding me that an explicit cast is a good idea. I like to compile without warnings at the highest pedantic level.
    I'll listen to this once I start seeing all of the function calls you post include casts like:
    Code:
    int c = (int)fgetc(stdin);
    (int)puts("Hello, world!");
    Why should memory allocation functions be a special case? Just do it correctly and you don't need to worry about it. Name your C source files with a .c extension like you're supposed to. Use a C compiler for your C source files like you're supposed to. Include header files for standard library functions you use like you're supposed to.
    If you understand what you're doing, you're not learning anything.

  13. #13
    Registered User
    Join Date
    Mar 2011
    Location
    Belgium
    Posts
    8
    Quote Originally Posted by itsme86 View Post
    I'll listen to this once I start seeing all of the function calls you post include casts like:
    Code:
    int c = (int)fgetc(stdin);
    (int)puts("Hello, world!");
    Why should memory allocation functions be a special case? Just do it correctly and you don't need to worry about it. Name your C source files with a .c extension like you're supposed to. Use a C compiler for your C source files like you're supposed to. Include header files for standard library functions you use like you're supposed to.
    Listen this is NOT solving my problem!

    We HAVE to use Visual Studio: C++ for our C coding, OK??

    I AM using .c files, I am using C headers only.

    Now I need a solution to MY problem, because I do NOT know how to solve it, please don't start a discussion about how the other guy was wrong about using a C++ compiler etc.

    This is how things are for me, and this is what my problem is, and I would LOVE an answer to MY problem..

    thank you..

  14. #14
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    I don't recall my compiler asking me whether I'd like C or C++. I suppose I can rename my .cpp to .c once it creates the first skeleton. But then I would know how to make it know the new file name. Remember, I'm using one honking big "mommy" Microsoft monster that's making me dumber, not smarter. Under "New Project" it only offers "Visual C++", "Other Languages: Visual Basic, Visual C#, and Visual J#" from Project Types.

  15. #15
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by eXcellion View Post
    Yes, I am using Visual Studio's C++ compiler (using .c) files..
    We have to use that compiler from uni...
    So set the compiler to C mode... it's right there in your settings panels.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Bug in Best-Fit Memory Allocation program (Simulation)
    By RommelTJ in forum C Programming
    Replies: 6
    Last Post: 12-13-2009, 04:43 PM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. dynamic memory allocation and returning pointers
    By sballew in forum C Programming
    Replies: 7
    Last Post: 11-03-2001, 03:21 PM