Thread: dynamic-variable-sized array

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    61

    dynamic-variable-sized array

    Hi there everyone,

    I am writing a function within which a 1D array increases in size (increasing number of elements) inside a loop.

    In order to achieve this I used the malloc() and realloc() statements, but neither one seems to allocate the memory correctly, producing an error in execution.

    Here is my code; should it not be clear enough, please let me know and Ill give you more information.

    thank you in advance,
    S.M.

    Code:
            int *_esup1;
    	int *_esup2;
    	int _nesup[nnode+1];
    	int _szesup1 = 1;
            int CONN[][3] = {{1,2,6},{2,7,6},{2,3,7},{3,8,7},{3,4,8},{4,9,8},{4,5,9},{5,10,9},{7,8,13},{8,12,13},{8,9,12},{9,11,12},{9,10,11}};
    
            _szesup1 = _esup2[nnode];
    	_esup1 = malloc((sizeof(int))*(_szesup1);
    	
    //Element pass 2: store the elements in _esup1:
    	for(_ielem=0; _ielem<=12; _ielem++){
    		for(_inode=0; _inode<=2; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    			_istor = _esup2[_ipoin-1] + 1;
    			_esup2[_ipoin-1] = _istor;
    			
    			_esup1 = malloc((sizeof(int))*(_istor));
    			printf("_istor %d\t size(ESUP1) %d\n",_istor, sizeof(_esup1));
    			_esup1[_istor] = _ielem;
    
    		}
    	}
    Last edited by simone.marras; 01-04-2009 at 03:07 PM.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You are using malloc twice, not malloc and realloc... Mistake?
    This, in turn, causes memory leaks.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you were using realloc, instead of malloc, then that would be a good start.

    When you do
    Code:
    _esup1 = malloc((sizeof(int)*(_istor));
    then the one thing you most assuredly do not have is
    Code:
    _esup1[_istor]
    If you ask for _istor elements (with malloc), then you get _istor elements, so trying to access the _istor+1'th element (with _esup1[_istor]) is not going to work very well.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    396
    You should check the result of malloc, if it's not a null pointer, then the allocation is correct and the runtime error (segv I assume) is due to an incorrect memory access, which is another problem.

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    61
    Hi there Elysia,

    Quote Originally Posted by Elysia View Post
    You are using malloc twice, not malloc and realloc... Mistake?
    This, in turn, causes memory leaks.
    I actually obtain the same error in executaion either by using malloc again inside the loop or realloc.

    Or better said, I do not get an error of memory allocation (sorry about that if I wrote that earlier), I do not get to fill the array at every loop step with the correct assignment of element values.

    At every loop step I am supposed to add a new element to the array, and assign it the value "_elem", but this does not happen

    Thank you again
    S.M.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by root4 View Post
    ...segv I assume...
    In Linux maybe. In Windows, that would probably be a page fault.
    It's not good to assume what OS someone is using.
    Regardless, I would just classify it as a crash and/or undefined behavior.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by simone.marras View Post
    Code:
            int *_esup1;
    	int *_esup2;
    	int _nesup[nnode+1]; // Is _nesup initialized?
    	int _szesup1 = 1;
            int CONN[][3] = {{1,2,6},{2,7,6},{2,3,7},{3,8,7},{3,4,8},{4,9,8},{4,5,9},{5,10,9},{7,8,13},{8,12,13},{8,9,12},{9,11,12},{9,10,11}};
    
            _szesup1 = _esup2[nnode]; // _esup2 is not initialized!!!
    	_esup1 = malloc((sizeof(int))*(_szesup1); // Size in _szesup1 is undefined!!!
    	
    //Element pass 2: store the elements in _esup1:
    	for(_ielem=0; _ielem<=12; _ielem++){
    		for(_inode=0; _inode<=2; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    			_istor = _esup2[_ipoin-1] + 1; // [B][COLOR="Red"]_esup2 is not initialized!!!
    			_esup2[_ipoin-1] = _istor;
    			
    			_esup1 = malloc((sizeof(int))*(_istor)); // To extend the storage of a block of memory, you must use realloc!
    			printf("_istor %d\t size(ESUP1) %d\n",_istor, sizeof(_esup1));
    			_esup1[_istor] = _ielem;
    
    		}
    	}
    Few comments.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Aug 2006
    Posts
    61
    Thank you again,

    Quote Originally Posted by Elysia View Post
    Few comments.
    about your comments, I agree but consider that the code I put is missing a whole part above where I allocate those variables that do not appear allocated in here (just for the sake of shortness in the thread); so, speakign fo that, the allocation of every other variable was done.

    Now though, I changed the malloc() inside the loop with the realloc as follows:

    Code:
    	
    for(_ielem=array_numb; _ielem<=nelem-1+array_numb; _ielem++){
    		for(_inode=array_numb; _inode<=max_nnode-1+array_numb; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    			_istor = _esup2[_ipoin-1] + 1;
    			_esup2[_ipoin-1] = _istor;
    			
    			_esup1 = realloc(_esup1, (sizeof(int))*(_istor));
    
    			printf("_istor %d\t size(ESUP1) %d\n",_istor, sizeof(_esup1));
    			_esup1[_istor] = _ielem;
    but I obtaine a memory allocation error now:

    Code:
    *** glibc detected *** ./testing.exe: realloc(): invalid next size: 0x175004a8 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7c89803]
    /lib/tls/i686/cmov/libc.so.6(realloc+0x10b)[0xb7c8b75b]
    ./testing.exe[0x8049195]
    ./testing.exe[0x80488c7]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7c32450]
    ./testing.exe[0x8048771]
    ======= Memory map: ========
    08048000-0804b000 r-xp 00000000 08:02 516097     /home/simone/Documents/scientific/CFD/myCFD_library/testing_myCFDlibrary/testing.exe
    0804b000-0804c000 rw-p 00002000 08:02 516097     /home/simone/Documents/scientific/CFD/myCFD_library/testing_myCFDlibrary/testing.exe
    0804c000-0806d000 rw-p 0804c000 00:00 0          [heap]
    17500000-17521000 rw-p 17500000 00:00 0 
    17521000-17600000 ---p 17521000 00:00 0 
    1764c000-b7bf7000 rw-p 1764c000 00:00 0 
    b7bf7000-b7c1a000 r-xp 00000000 08:02 2293788    /lib/tls/i686/cmov/libm-2.7.so
    b7c1a000-b7c1c000 rw-p 00023000 08:02 2293788    /lib/tls/i686/cmov/libm-2.7.so
    b7c1c000-b7d65000 r-xp 00000000 08:02 2293784    /lib/tls/i686/cmov/libc-2.7.so
    b7d65000-b7d66000 r--p 00149000 08:02 2293784    /lib/tls/i686/cmov/libc-2.7.so
    b7d66000-b7d68000 rw-p 0014a000 08:02 2293784    /lib/tls/i686/cmov/libc-2.7.so
    b7d68000-b7d6c000 rw-p b7d68000 00:00 0 
    b7d6c000-b7d9c000 r-xp 00000000 08:02 681117     /usr/local/lib/libgslcblas.so.0.0.0
    b7d9c000-b7d9d000 rw-p 0002f000 08:02 681117     /usr/local/lib/libgslcblas.so.0.0.0
    b7d9d000-b7f1c000 r-xp 00000000 08:02 681124     /usr/local/lib/libgsl.so.0.10.0
    b7f1c000-b7f26000 rw-p 0017f000 08:02 681124     /usr/local/lib/libgsl.so.0.10.0
    b7f2e000-b7f38000 r-xp 00000000 08:02 2294001    /lib/libgcc_s.so.1
    b7f38000-b7f39000 rw-p 0000a000 08:02 2294001    /lib/libgcc_s.so.1
    b7f39000-b7f3c000 rw-p b7f39000 00:00 0 
    b7f3c000-b7f3d000 r-xp b7f3c000 00:00 0          [vdso]
    b7f3d000-b7f57000 r-xp 00000000 08:02 2295295    /lib/ld-2.7.so
    b7f57000-b7f59000 rw-p 00019000 08:02 2295295    /lib/ld-2.7.so
    bff85000-bff9a000 rw-p bffeb000 00:00 0          [stack]
    Aborted
    thank you again for all the help and patience!

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Then, if you please, can you post the smallest possible sample that demonstrates the problem? I have a hard time sorting through all of the variables and what they do, as well as what values they contain.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Code:
    for(_ielem=array_numb; _ielem<=nelem-1+array_numb; _ielem++){
    		for(_inode=array_numb; _inode<=max_nnode-1+array_numb; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    			_istor = _esup2[_ipoin-1] + 1; //?
    			_esup2[_ipoin-1] = _istor; //?
    			
    			_esup1 = realloc(_esup1, (sizeof(int))*(_istor));
    
    			printf("_istor %d\t size(ESUP1) %d\n",_istor, sizeof(_esup1));
    			_esup1[_istor] = _ielem;  //BOOOM!
    So (1) Why realloc one more every time (I think that's what the two lines labeled //? are supposed to do, but it's not quite clear where the numbers are coming from), and (2) the line labeled //BOOOM! is still a really really really really big error.

  11. #11
    Registered User
    Join Date
    Aug 2006
    Posts
    61
    Quote Originally Posted by Elysia View Post
    Then, if you please, can you post the smallest possible sample that demonstrates the problem? I have a hard time sorting through all of the variables and what they do, as well as what values they contain.
    Sorry about that, sure, here a more readable version of the code with the correct allocation of the used variables; I hope this helps

    Code:
           int *_esup1;
    	int *_esup2;
           int _szesup1;
            int CONN[][3] = {{1,2,6},{2,7,6},{2,3,7},{3,8,7},{3,4,8},{4,9,8},{4,5,9},{5,10,9},{7,8,13},{8,12,13},{8,9,12},{9,11,12},{9,10,11}};
    
           //Allocate _esup2:
    	_esup2 = (int*) malloc((sizeof(int[nnode+1])));
    
           //First allocation of _esup1:
            _szesup1 = 1;
    	_esup1 = malloc((sizeof(int))*(_szesup1); 
    	
           //Store the elements in _esup1:
    	for(_ielem=0; _ielem<=12; _ielem++){
    		for(_inode=0; _inode<=2; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    
    			_istor = _esup2[_ipoin-1] + 1;
    
    			_esup2[_ipoin-1] = _istor;
    			
    			_esup1 = realloc(_esup1, (sizeof(int))*(_istor));
    
    			_esup1[_istor] = _ielem;
    
    		}
    	}
    thank you very much (Ill be back in about 45 minutes, so if I doent reply it's not for rudeness!)
    S.M.

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    nnode, _istor and _ipoin is missing... I'll try hacking them in.
    EDIT: Done. Got a crash. I will investigate.
    Last edited by Elysia; 01-04-2009 at 03:37 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Had a question about the lines highlighted red.
    Code:
           int *_esup1;
    	int *_esup2;
           int _szesup1;
            int CONN[][3] = {{1,2,6},{2,7,6},{2,3,7},{3,8,7},{3,4,8},{4,9,8},{4,5,9},{5,10,9},{7,8,13},{8,12,13},{8,9,12},{9,11,12},{9,10,11}};
    
           //Allocate _esup2:
    	_esup2 = (int*) malloc((sizeof(int[nnode+1])));
    
           //First allocation of _esup1:
            _szesup1 = 1;
    	_esup1 = malloc((sizeof(int))*(_szesup1); 
    	
           //Store the elements in _esup1:
    	for(_ielem=0; _ielem<=12; _ielem++){
    		for(_inode=0; _inode<=2; _inode++){
    		//Update storage counter, storing in _esup1:
    			_ipoin = CONN[_ielem][_inode];
    
    			_istor = _esup2[_ipoin-1] + 1; /* _esup2 is not initialized yet */
    
    			_esup2[_ipoin-1] = _istor; /* sequence?? shouldn't the one above come after this one */
    			
    			_esup1 = realloc(_esup1, (sizeof(int))*(_istor));
    
    			_esup1[_istor] = _ielem;
    
    		}
    	}

  14. #14
    Registered User
    Join Date
    Aug 2006
    Posts
    61
    Quote Originally Posted by Elysia View Post
    nnode, _istor and _ipoin is missing... I'll try hacking them in.
    EDIT: Done. Got a crash. I will investigate.
    Im back; here some numbers and types that I am actually using to run this:

    int _ielem;
    int _inode;
    int _istor;
    int nnode = 13;

  15. #15
    Registered User
    Join Date
    Aug 2006
    Posts
    61
    I have a main.c written on purpose to test this function; I can send them both to you by this thread if you think it may help. The reason why I ask is due to the fact that the main.c and the function use much more variables than those already appearing in this thread, and that may cause some confusion.

    Please those interested, let me know if you want the two codes as well

    Thanks you
    S.M.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic Array
    By firetheGlazer in forum C Programming
    Replies: 4
    Last Post: 07-11-2008, 11:57 AM
  2. Replies: 2
    Last Post: 07-11-2008, 07:39 AM
  3. Replies: 4
    Last Post: 11-02-2006, 11:41 AM
  4. Variable Allocation in a simple operating system
    By awkeller in forum C Programming
    Replies: 1
    Last Post: 12-08-2001, 02:26 PM
  5. making an array name a variable
    By Zaarin in forum C++ Programming
    Replies: 5
    Last Post: 09-02-2001, 06:17 AM