Thread: Is it mandatory to allocate space for the pointers in arrays?

  1. #1
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357

    Is it mandatory to allocate space for the pointers in arrays?

    Hello to all.

    Assume that we have :

    Code:
    char *planets[] = { "Mercury" , "Venus" , "Earth" };
    the size will be 3 planets[0] , [1] and [2]. Why we must allocate space for pointers on this array? I am reading aboyt dynamic memory allocation which is a great way to avoid wasting amount of memory but here on this particular example is there any waste of memory ? why we have to allocate space for pointers?

    Thank you in advance

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    you have array of 3 pointers pointing to static strings (not changeable) so pointer should be declared const
    Code:
    const char *planets[] = { "Mercury" , "Venus" , "Earth" };
    If you are planning only read this strings - you do not need to allocate the memory.
    If you are planning to write to this location something else later - you need to have buffers big enough to store you updated strings.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by vart View Post
    you have array of 3 pointers pointing to static strings (not changeable) so pointer should be declared const
    Code:
    const char *planets[] = { "Mercury" , "Venus" , "Earth" };
    If you are planning only read this strings - you do not need to allocate the memory.
    If you are planning to write to this location something else later - you need to have buffers big enough to store you updated strings.
    Ok. Because I was in doubt... King's Book* writes "Although we have had to allocate space for the pointers" when it shows this example. Maybe it means when you need to store string where are not literals as you said before.

    * http://knking.com/books/c2/index.html
    Last edited by Mr.Lnx; 07-04-2013 at 03:22 AM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Mr.Lnx View Post
    Why we must allocate space for pointers on this array?
    We don't. The compiler does. All variables, and arrays, are represented using memory. That means your definition is of three pointers, each of which contains the address of a (first character in a) string literal. The string literals will be represented in memory somewhere - otherwise a pointer cannot point at them.

    Quote Originally Posted by Mr.Lnx View Post
    I am reading aboyt dynamic memory allocation which is a great way to avoid wasting amount of memory but here on this particular example is there any waste of memory ?
    Dynamic memory allocation is not about avoiding waste of memory. It is about being able to allocate, use, and deallocate memory in circumstances where the amount need is not necessarily known at compile time.

    In your example, there is no waste of memory. Three string literals will be created. Three pointers will be created, and initialised so they point at the first characters in those string literals. The array of pointers will not longer exist - at least as far as the program is concerned, unless it does something with undefined behaviour - when the containing scope ceases to exist (e.g when the function returns). The string literals will also be stored in some location in memory, but it is up to the compiler how or if data remains stored in memory (e.g. is it placed somewhere in read-only memory). String literals are hard coded in your program, so the data for them has to be stored somewhere. If the program reads the string literals directly from the executable file, it is conceivable that they are not stored in memory if not needed. However, it is more common that the string literals are stored in memory somewhere - for example in read-only memory - as re-reading data from an executable file on disk more than necessary will typically be grossly inefficient at run time.

    Quote Originally Posted by Mr.Lnx View Post
    why we have to allocate space for pointers?
    As I said, you don't. Either the book you are using is badly wrong, or you have badly misinterpreted the information it has given. Or both.

    I'm not familiar with the book, and don't have access to the text, so don't have enough information to elaborate any further.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    grumpy we are the people who control the compiler. That is why I used "we".

    Finally you are right about dynamic memory allocation it was my bad quickness. Anyway Book writes that there is no any wasted characters in the string of course but after from that "Although we have had to allocate space for the pointers in the planets array".

    I can't understand this sentence really... so if none has the book from here there is no problem.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Yeah, okay.

    At a guess, the book is fussing over the fact that there is memory allocated for each of the string literals, as well as the array of pointers.

    The alternative would be two define a two-dimensional array to hold the strings. Such an array cannot be initialised directly with a set of string literals (strcmp() needs to be used, which implies each string literal is stored in memory elsewhere). But, assuming (say) that the strings to be stored in an array are loaded from a file AND that all the strings are of similar lengths, it might be possible to save some small memory usage by using a 2D array rather than an array of pointers to string literals.

    My general take is to do whatever works, and is easiest to code, rather than fussing over differences of a few bytes of memory usage with different methods. If you have to worry about the difference of amounts of memory between a 2D array initialised to hold strings, and an array of pointers to string literals, then odds are your host system and program have very little free memory, and your program will have trouble running at all.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  7. #7
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by Mr.Lnx View Post
    Finally you are right about dynamic memory allocation it was my bad quickness. Anyway Book writes that there is no any wasted characters in the string of course but after from that "Although we have had to allocate space for the pointers in the planets array".
    A typical compiler will "allocate" the space at compile time in the "data" segment of a program, which is different than dynamic allocation which gets space from the heap or from the stack.

  8. #8
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    @grumpy check the two versions of one program :

    Code:
    /* remind.c */
    
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAX_REMIND 50  //Μέγιστος αριθμος υπενθυμίσεων
    #define MSG_LEN 60     //Μέγιστο μήκος μηνύματος υπενθύμισης
    int read_line(char str[] , int n);
    
    int main( void )
    {
    	char reminders[MAX_REMIND][MSG_LEN+3];  
    	char day_str[3] , msg_str[MSG_LEN+1]; // Oρίζει το msg_str με MSG_LEN + 1 χαρακτήρες αρα δεν βγαινει εκτος ορίων στην αποθήκευση του '\0' στην read_line.
    	
    	int day , i , j , num_remind=0;       
    	
    	for(;;){
    		if( num_remind == MAX_REMIND){
    			printf("-- No space left --\n");
    			break;
    		}
    	    printf(" Enter day and reminder : ");
    	    scanf("%2d", &day);        // Διάβασμα της ημέρας
    	    
    	    if( day == 0 || day < 0 || day > 31)
    	    	break;
    		
    	    sprintf(day_str , "%2d" , day);  
    	    
    	    read_line(msg_str, MSG_LEN); // Διάβασμα της υπενθύμισης 
    	    
    	    for(i=0; i < num_remind; i++)
    		if(strcmp(day_str , reminders[i]) < 0 )   
    			break;  // Απο αυτο τον βροχο βγαίνουμε οχι απο τον for(;;) 
    	    
    	    for(j=num_remind; j>i; j--)
    		strcpy(reminders[j], reminders[j-1]);  
    
    		strcpy(reminders[i] , day_str);
    		strcat(reminders[i] , msg_str);
    	    
    		num_remind++;
    	}
    	
    	if( !num_remind )
    		exit(1);
    	
    	printf("\nDay Reminder\n");
    	
    	for(i=0; i < num_remind; i++)
    		printf(" %s\n" , reminders[i]);
    		
            return 0;
    }
    //----------------------------------------------------------------------
    int read_line(char str[] , int n)
    {
    	int ch , i =0 ;
    	
    	while( (ch= getchar()) !='\n' && i<n)  
    		str[i++]= ch;
    	
    	str[i]='\0';
    	
    	return i;
    }
    //----------------------------------------------------------------------
    If you want to you can ignore the comments they are in greek language.

    and remind2.c

    Code:
    /* remind2.c */
    
    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define MAX_REMIND 50  //Μέγιστος αριθμος υπενθυμίσεων
    #define MSG_LEN 60     //Μέγιστο μήκος μηνύματος υπενθύμισης
    int read_line(char str[] , int n);
    
    int main( void )
    {
    	char *reminder[MAX_REMIND]; 
    	char day_str[3] , msg_str[MSG_LEN+1]; // Oρίζει το msg_str με MSG_LEN + 1 χαρακτήρες αρα δεν βγαινει εκτος ορίων στην αποθήκευση του '\0' στην read_line.
    	
    	int day , i , j , num_remind=0;       
    	
    	for(;;){
    		if( num_remind == MAX_REMIND){
    			printf("-- No space left --\n");
    			break;
    		}
    	    printf(" Enter day and reminder : ");
    	    scanf("%2d", &day);        // Διάβασμα της ημέρας
    	    
    	    if( day == 0 || day < 0 || day > 31)
    	    	break;
    		
    	    sprintf(day_str , "%2d" , day);  
    	    
    	    read_line(msg_str, MSG_LEN); // Διάβασμα της υπενθύμισης 
    	    
    	    for(i=0; i < num_remind; i++)
    		if(strcmp(day_str , reminders[i]) < 0 )   
    			break;  // Απο αυτο τον βροχο βγαίνουμε οχι απο τον for(;;) 
    	    
    	    for(j=num_remind; j>i; j--)
    		reminders[j] = reminders[j-1];  //Kάθε γραμμή του πίνακα περιέχει ένα string 
    
                    reminder[i] = malloc(2 + strlen(msg_str) + 1 );  // 2 για την ημέρα + μήκος υπενθύμισης + '\0'
                   if(reminders[i] == NULL){
    	            printf("--No space left--\n");
    	           break;
                   }
    		strcpy(reminders[i] , day_str);
    		strcat(reminders[i] , msg_str);
    	    
    		num_remind++;
    	}
    	
    	if( !num_remind )
    		exit(1);
    	
    	printf("\nDay Reminder\n");
    	
    	for(i=0; i < num_remind; i++)
    		printf(" %s\n" , reminders[i]);
    		
            return 0;
    }
    //----------------------------------------------------------------------
    int read_line(char str[] , int n)
    {
    	int ch , i =0 ;
    	
    	while( (ch= getchar()) !='\n' && i<n)  
    		str[i++]= ch;
    	
    	str[i]='\0';
    	
    	return i;
    }
    //----------------------------------------------------------------------
    I think that we can say we avoid some space of wasting memory with the dynamic memory allocation. The program is a reminder ... if you want comments I can add in English.
    Last edited by Mr.Lnx; 07-04-2013 at 01:31 PM.

  9. #9
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by Mr.Lnx View Post
    dynamic memory allocation.
    Neither program is using dynamic memory allocation (which would be malloc() or if C++ new ... ). For both program examples, at compile time, the compiler will reserve space on the stack for the messages and reminders.

  10. #10
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by rcgldr View Post
    Neither program is using dynamic memory allocation (which would be malloc() or if C++ new ... ). For both program examples, at compile time, the compiler will reserve space on the stack for the messages and reminders.
    *reminder[MAX_REMIND] is an array of dynamically allocated strings...

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    What, you're claiming that the one using dynamic memory allocation wastes memory?!
    The one using fixed size buffers wastes memory because the buffer has to be big enough for the longest possible string, whereas the one using dynamic memory allocation only allocates as many bytes as is actually needed.

    In other words, you've got it backwards.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by iMalc View Post
    What, you're claiming that the one using dynamic memory allocation wastes memory?!
    Where? show me.

    Quote Originally Posted by iMalc View Post
    The one using fixed size buffers wastes memory because the buffer has to be big enough for the longest possible string, whereas the one using dynamic memory allocation only allocates as many bytes as is actually needed.

    In other words, you've got it backwards.
    Yes. The first version (remind.c) uses an array reminder[MAX_REMIND][MSG_LEN+3]; this means #MAX_REMIND arrays of MSG_LEN+3 elements. In the second version (remind2.c) instead we only have *reminder[MAX_REMIND] which contains dynamically allocated strings with ( 2 + strlen(msg_str) + 1 ) size . Each element is a pointer to a dynamically allocated string finally we don't need the strcpy of the first version because we can use the pointers reminder[j] = reminders[j-1];
    Last edited by Mr.Lnx; 07-04-2013 at 03:03 PM.

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by rcgldr View Post
    Neither program is using dynamic memory allocation (which would be malloc() or if C++ new ... ). For both program examples, at compile time, the compiler will reserve space on the stack for the messages and reminders.
    Tried to edit this, but had browser or internet problems. the second program is dynamically allocating buffers for the strings (using malloc()).

  14. #14
    Registered User
    Join Date
    Sep 2011
    Location
    Athens , Greece
    Posts
    357
    Quote Originally Posted by rcgldr View Post
    Tried to edit this, but had browser or internet problems. the second program is dynamically allocating buffers for the strings (using malloc()).
    Yes. Of course... because just for a moment I thought... what he said to me? I am going crazy

    Anyway I think (according to my previous post) that I have understood well what two versions of the program do. If there is some misunderstanding from my side please tell me.

    Sorry for my english is not my native language , I am reading on daily basis an English book but it is not the same compared with a native english or American speaker. Never gonna be the same unfortunately. Thank you
    Last edited by Mr.Lnx; 07-05-2013 at 12:15 AM.

  15. #15
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by Mr.Lnx View Post
    " ... allocate space for the pointers ... "
    Quote Originally Posted by rcgldr View Post
    The second program is dynamically allocating buffers for the strings (using malloc()).
    Quote Originally Posted by Mr.Lnx View Post
    If there is some misunderstanding from my side please tell me.
    The point from my earlier post is that neither example program in post #8 dynamically allocates space for pointers.

    The first example program in post #8 does not use any pointers (so no space is needed for pointers), instead it declares a two dimensional array:

    Code:
        char reminders[MAX_REMIND][MSG_LEN+3];
    The second program in post #8 does not dynamically allocate space for the pointers, instead it declares an array of pointers:

    Code:
        char *reminder[MAX_REMIND];
    Here is a link to example source code that allocates space for an array of pointers, then does a single allocation for all the rows.

    2D dynamic array in continuous memory locations (C) | G. Samaras

    The article also has a link to that shows other code examples of allocating space for an array of pointers.

    2D dynamic array (C) | G. Samaras
    Last edited by rcgldr; 07-05-2013 at 04:01 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 12-11-2012, 03:19 PM
  2. allocate space
    By Chris_1980 in forum C Programming
    Replies: 5
    Last Post: 06-10-2010, 07:28 AM
  3. Replies: 7
    Last Post: 05-19-2010, 02:12 AM
  4. Allocate space for 2d array
    By jtay in forum C Programming
    Replies: 7
    Last Post: 04-25-2010, 10:34 PM
  5. allocate no space for dynamic array~
    By black in forum C++ Programming
    Replies: 2
    Last Post: 06-11-2004, 06:28 AM