Qbasicnews.com

Full Version: REDIM equivalent in C?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Is there an equivalent of the QB REDIM in C, so I can dynamically allocate arrays? Because I need to specify a variable, not a constant, for the array subscript upon declaration.
Yep.

Code:
#include <stdlib.h>

void test(void) {
  char *varString;

  /* Allocate a 10 byte string */
  varString = malloc(sizeof(10 * sizeof(char));

  /* Reallocate varString as a 20 byte string */
  varString = realloc(varString, 20 * sizeof(char));
}

Info on realloc is here: http://www.opennc.org/onlinepubs/7908799...alloc.html
Okay, thanks, but two more questions:
1) Why do you place the times-ten multiplication inside the sizeof function? Why don't you just do varString=malloc(10 * sizeof(char));?
2) If I declare an array without malloc, but like this:
Code:
char varString[10];
Can I still do this:
Code:
realloc(varString,11*sizeof(char));
To make varString have 11 elements instead of 10?
Quote:1) Why do you place the times-ten multiplication inside the sizeof function? Why don't you just do varString=malloc(10 * sizeof(char));?

Opps, thats a typo on my part. I usually use the sizeof operator when allocating space because it can help avoid portability issues. Technically you dont need the sizeof operator when using chars, because the C standard guarantees that chars are exactly one byte, the malloc line should have read:
Code:
varString = malloc(10 * sizeof(char));
But the following is also fine:
Code:
varString = malloc(10);

In answer to question 2, I don't think so. You can always do this though:
Code:
char *array;
  
  /* Allocate 10 bytes */
  array = malloc(10 * sizeof(char));

  /* Reallocate to 20 bytes */
  array = realloc(20 * sizeof(char));

  /* Set and element in the array */
  array[15] = 'x';
  printf("array[15] = %c\n", array[15]);

Which isn't too much more difficult than working with conventional arrays. You should try and learn pointers if you are serious about getting into C/C++ anyway, even the most basic of C/C++ programs use pointers.
Um...heheh, you're wrong on the second question. :wink:
I tried this code:
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int array[3]={3,6,3};
realloc(array,4*sizeof(int));
array[4]=5;
printf("%d",array[4]);
return 0;
}
Worked just fine. Big Grin
Of course it works... in your compiler Wink That is not good practice. That code is not portable and what you are doing is bad memory management. You create a static array, then realloc it. What realloc does is looking if it can expand the allocated memory to fit the new size. If you try this with a static array it won't be able to expand the array where it is ('cause most likely it will be packed with all the static data, so it is surrounded by allocated memory) so it will have to look somewhere else in memory to create a new array with the new size. If the reallocated array were dynamic, no prob: it creates a new, bigger array somewhere lese and frees the memory formerly used, but... how do you free the memory used by something static? You can't! So you end having 10 bytes in the static memory unreferenced but allocated (so you can't use that memory for anything) and 11 bytes for the new array.

Note that in C arrays should be thought of differently. In C, an array is just some allocated memory and a pointer to the beginning of this memory. When you allocate an array (staticly or dynamicly) you just reserve some bytes and create a pointer to that section of memory. That's why there is no such a thing like boundary checking.

And pointers are not difficult to understand. Think about a variable that instead of a numeric value it has some kind of link or pointer to somewhere in memory. Like it contains an address. It is some kind of what you do in QB:

Code:
a% = VARPTR(array%(0))
Okay, Nath...so that means that whenever I might need to realloc(), I should create the array dynamically, using malloc()?
And one other question, why do the file-handling commands use pointers to types FILE, instead of just passing the actual object?
1. Yes Smile

2. Because C++ is a hack and all that FILE * stuff is inherited from the C language, so it uses the C way of life.
Er...I'm using C. And that doesn't really answer my question of why, in the first place, do we use a pointer instead of an plain record?
Ah, you said "the actual object" and I got puzzled Tongue Objects<>Structures Smile

Why? I dunno, just a matter of implementation. File functions expect a pointer to the FILE struct. Anyhow, that way is better, 'cause you have your file struct defined just once and don't need to make a copy everytime you need it. When you pass a parameter by value it is copied spending time and memory. When you pass a parameter by reference (that means passing a pointer to it) the function just knows where the data is in memory (thru the pointer) and operates with it.

That way you can (for example) set up a function that return several values:

Code:
void alterValues(int a, int b, int *sum, int *subs)
{
   *sum = a + b;
   *subs = a - b;
}

int main(void)
{
   int a = 10, b = 5;
   int s1, s2;

   alterValues (a, b, &s1, &s2);

   printf("%i+%i=%i; %i-%i=%i\n",a,b,s1,a,b,s2);
}

When you call to alterValues you are passing a and b by value (making a copy) and the address of s1 and s2 (that's what "&" makes: gets the address of a variable, that is, makes a pointer to a variable, sorta what VARSEG and VARPTR do). alterValues is taking two integers and two pointers to integers. When you do *sum = a + b; it means "in the memory position pointed by sum, write 'a+b' ", so it is altering memory directly and when the function ends you have the memory altered, so s1 = a+b and s2 = a-b.

Note that the FILE structure has stuff like your position inside the file which may be altered by some functions (fgetc, fread, fwrite and stuff like that) so it is needed to pass a pointer to those functions so if they change the FILE struct the changes are effective outside those functions.
Pages: 1 2