strncpy and a structure array in C
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17

Thread: strncpy and a structure array in C

  1. #1
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147

    strncpy and a structure array in C

    Hi, I have the below program...
    Code:
    // structure_arrays.c:
    
    #include <stdio.h>
    #include <string.h>
    
    struct index
    {
    	int		page;
    	char	*title;
    };
    
    int main()
    {
    	int i = 0;
    	struct index *structure_array[10];
    
    	for(; i < 10; i++)
    	{
    		structure_array[i] -> page = i * 10;
    		strncpy(structure_array[i] -> title, (char *)(i * 2), (size_t)2);
    	}
    
    	for(i = 0; i < 10; i++)
    		printf("%s %d\n", structure_array[i] -> title, structure_array[i] -> page);
    
    	return 0;
    }
    ...and one of the irritating problems that I'm getting is that when I try to execute the program(it compiles without a hitch), it crashes. I narrowed the problem down to the first use of "structure_array", but I'm not sure how to fix it. Thanks in advance.
    Favorite music:
    Rammstein
    E nomine
    Prodigy

    "Beer, the solution and the cause of all of our problems" -- Homer Simpson

  2. #2
    Join Date
    Apr 1999
    Posts
    27,423
    Code:
    strncpy(structure_array[i] -> title, // <--  Uninitialized pointer!!!
    The title pointer is uninitialized, i.e. it's pointing to a random spot in memory, and you're writing characters to it. Of course it may crash. As a matter of fact, you have an entire array of uninitialized pointers to your struct (structure_array).

    I'm sure the C or C++ book you're using discusses pointers and why they must point somewhere valid before you write (or even read) where they point to.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; March 29th, 2004 at 11:59 PM.

  3. #3
    Join Date
    Jun 2002
    Posts
    137
    Code:
    struct index *structure_array[10];
    This array for index * is also uninitialized, structure_array[i] -> page will cause problem too, right? I am not sure.

  4. #4
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    How would one go about initializing the pointers(in this particular situation, that is)?
    Favorite music:
    Rammstein
    E nomine
    Prodigy

    "Beer, the solution and the cause of all of our problems" -- Homer Simpson

  5. #5
    Join Date
    Apr 1999
    Posts
    27,423
    How would one go about initializing the pointers(in this particular situation, that is)?
    We don't know what your situation is. If you designed the code to use pointers, you should have at least some idea of what you wanted to do with these pointers, including initialization -- pointers are useless unless you initialize them. Since there are multiple ways to initialize a pointer, then whatever advice you get may not fit into the situation that you intended.

    So did you intend to point the pointers to local index structs, allocate dynamically and point the pointers there, etc.?

    Also, why do you need to use pointers and not just an array of 10 structs?
    Code:
    struct index structure_array[10];
    This takes care of one problem. The next problem is the title.

    Since you state this is C (not C++), you must allocate room for the title, since you just can't copy bytes to an undetermined part of memory.
    Code:
    int i;
    for (i = 0; i < 10; ++i )
        structure_array[ i ].title = malloc( 1000 * sizeof( char ) ); // room for 1,000 characters
    But then, you have to make sure you call free() on each of these pointers.

    If this were C++, then you should use std::string and not char * for the title. Then you don't need to allocate or free anything.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    Originally poste by Paul McKenzie
    Also, why do you need to use pointers and not just an array of 10 structs?
    Well, originally I set out to improve my understanding of pointers when I started out with this program(as you can see I'm progressing quite well right now ). I was hoping that by working directly with pointers, it would also give me extra 'control' over my program.

    The book that you mentioned earlier does talk about pointers(quite well actually). However, it does not give a good example directly relating to my problem, that and it's written in German(I'm a study abroad student in Germany, hence my friends know only good C book in German not english), which makes it difficult for me to learn this stuff since I don't speak fluent German, but I'm making my through. Oh, one more thing, I re-did some of the things in my program(which doesn't work, sigh)...
    Code:
    // structure_pointer_arrays.c:
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct index
    {
      int page;
      char *title;
    };
    
    int main()
    {
      int i = 0;
      struct index *structure_array[10];
    
      for(; i < 10; i++)
      {
        structure_array[i] -> title = (char *)malloc(5);
      }
    
      for(i = 0; i < 10; i++)
      {
        structure_array[i] -> page = i * 10;
        strncpy(structure_array[i] -> title, (char *)(i * 2), (size_t)2);
      }
    
      for(i = 0; i < 10; i++)
        printf("%s %d\n", structure_array[i] -> title, structure_array[i] -> page);
    
      for(i = 0; i < 10; i++)
      {
        free(structure_array[i] -> title);
      }
    
      return 0;
    }
    ... what I want to do is just have it input a bunch of characters and number into the structure array via pointers(maybe dereferncing them and then inputting the characters one by one).

  7. #7
    Join Date
    Apr 1999
    Posts
    27,423
    Originally posted by ats007spdou
    Code:
    // structure_pointer_arrays.c:
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct index
    {
      int page;
      char *title;
    };
    
    int main()
    {
      int i = 0;
      struct index *structure_array[10];
    
      for(; i < 10; i++)
      {
        structure_array[i] -> title = (char *)malloc(5);
    The structure_array[i] is still unininitalized. You have an array of 10 uninitialized pointers, therefore you are going to get undefined behavior.

    Code:
    typedef struct tagindex
    {
      int page;
      char *title;
    } index;
    
    int main()
    {
      int i = 0;
      index *structure_array;
    
      // Allocate room for 10 structure_array elements.
      structure_array = malloc( 10 * sizeof(index));
    
       /* ... at the end of the code */
       free(structure_array);
    Also, are you sure title won't be more than 5 characters (including the terminating NULL character)? If it will be, then you did not allocate enough space and you're overwriting memory.

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    Originally posted by Paul McKenzie
    The structure_array[i] is still unininitalized.
    Yes, that's because I have no idea how to do that in this instance.

  9. #9
    Join Date
    Jun 2003
    Location
    Gjøvik, Norway
    Posts
    204
    You need to allocate memory for the index-structs the pointer-array points to before you can allocate memory for it's members.
    Code:
    int main()
    	{
    	int i = 0;
    	struct index *structure_array[10];
    
    	for(; i < 10; i++)
    		{
    		structure_array[i] = malloc(sizeof(struct index));
    		}
    	...

  10. #10
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    ::sigh::, nothing works, here's my code, I'm surely doing something wrong...
    Code:
    // structure_pointer_arrays.c:
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct tagindex
    {
      int page;
      char *title;
    } index;
    
    /*struct index
    {
      int  page;
     char	*title;
    };*/
    
    int main()
    {
      int i = 0;
      //struct index *structure_array[10];
    
      struct index *structure_array[10];
    
      for(; i < 10; i++)
      {
        structure_array[i] = malloc(sizeof(struct index));
      }
    
      for(i = 0; i < 10; i++)
      {
        structure_array[i] -> page = i * 10;
        strncpy(structure_array[i] -> title, (char *)(i * 2), (size_t)2);
      }
    
      for(i = 0; i < 10; i++)
        printf("%s %d\n", structure_array[i] -> title, structure_array[i] -> page);
    
      free(structure_array);
    
      return 0;
    }
    ...and here are the errors...
    Code:
    :\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(28) : error C2027: use of undefined type 'index'
            C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(24) : see declaration of 'index'
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(33) : error C2037: left of 'page' specifies undefined struct/union 'index'
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(34) : error C2037: left of 'title' specifies undefined struct/union 'index'
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(34) : warning C4047: 'function' : 'const char *' differs in levels of indirection from 'unsigned int '
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(34) : warning C4024: 'strncpy' : different types for formal and actual parameter 2
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(34) : error C2198: 'strncpy' : too few actual parameters
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(38) : error C2037: left of 'title' specifies undefined struct/union 'index'
    C:\Documents and Settings\Andrew Shrets\My Documents\Programming\Linux C\!!!Further!!!\structure_pointer_arrays\structure_pointer_arrays.c(38) : error C2037: left of 'page' specifies undefined struct/union 'index'
    Error executing cl.exe.
    
    structure_pointer_arrays.exe - 6 error(s), 2 warning(s)
    ...if someone gets this junk to work, I will worship them.

  11. #11
    Join Date
    Jun 2003
    Location
    Gjøvik, Norway
    Posts
    204
    Sorry... Some of that's my fault. (You shuldn't have the struct keyword inside the sizeof therem, and you shoud add (index*) in front of malloc) Been a while since I looked at plain C. I didn't see Paul's working example code at the bottom there either... That code does the same thing.

    But anyhoo.. Where did the allocation for title go? You can't remove that even though you allocate the index structs. You need to allocate ALL memory that is pointed to by pointers unless you point them at variables allocated on the stack! (Which you do not!)
    Last edited by Assmaster; March 30th, 2004 at 10:48 AM.

  12. #12
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    I think I'll come back to this topic in a week or so, when I have a far better grasp on structures and pointers. That and I'm not feeling all that well right now, but thanks for your help guys.

  13. #13
    Join Date
    Jun 2003
    Location
    Gjøvik, Norway
    Posts
    204
    Wait.. Don't leave!
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define MAX_TITLE_LENGTH 50
    
    typedef struct tagindex
    	{
    	int page;
    	char *title;
    	} index;
    
    int main()
    	{
    	int i;
    	index* structure_array[10];
    
    	for(i = 0; i < 10; i++)
    		{
    		structure_array[i] = (index*)malloc(sizeof(index));
    		structure_array[i]->title = (char*)malloc(MAX_TITLE_LENGTH);
    		}
    
    	for(i = 0; i < 10; i++)
    		{
    		structure_array[i]->page = i * 10;
    		strcpy(structure_array[i]->title, "Some title");
    		}
    	
    	for(i = 0; i < 10; i++)
    		printf("%s %d\n", structure_array[i]->title, structure_array[i]->page);
    
    	for(i = 0; i < 10; i++)
    		{
    		free(structure_array[i]->title);
    		free(structure_array[i]);
    		}
    		
    	system("pause");
    	return 0;
    	}
    But yeah... Starting with a very simple example is always a good thing when learning pointers. This might be a bit over the top if you just started.

  14. #14
    Join Date
    Feb 2004
    Posts
    45

    First fix your syntax

    Well you have one big mistake in using the typedef mechanism:
    You have declared:
    Code:
    typedef struct tagindex
    {
    	int page;
    	char *title;
    } index;
    That means that "index" is another name for the new type that is called "struct tagindex".
    In light of that you may not say:
    Code:
    struct index *structure_array[10];
    But rather:
    Code:
    struct tagindex *structure_array[10];
    // Or Better
    index *structure_array[10];
    And you may not say:
    Code:
    structure_array[i] = malloc(sizeof(struct index));
    But rather:
    Code:
    structure_array[i] = malloc(sizeof(struct tagindex));
    // Or better
    structure_array[i] = malloc(sizeof(index));
    But ofcourse fixing this mistake will only let you compile the program, you have more mistakes ...

    Nimrod Fireman

  15. #15
    Join Date
    Apr 2003
    Location
    Regensburg, Bavaria, Germany
    Posts
    147
    Originally posted by me
    ...if someone gets this junk to work, I will worship them.
    Currently I'm building a marble and gold encrusted temple dedicated to Assmaster, which will be in the shape of 2 giant cheeks petruding on top of Mt. Everest, so that everyone will be able to see its greatness, even from space.

    P.S.: And no, I worked with pointers before, this is just something I wanted to try, thanks for the help.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center