-2

I'm trying to allocate memory for an array in C and I'm getting an error. No idea what's wrong, here. The error is yelling at me regarding pBuffer.

//Allocate memory
const int BLOCK_SIZE = 512;
int *BLOCK_MEM = (int *)malloc(sizeof(int) * 512);
int buffer[BLOCK_SIZE];
int *pBuffer = &buffer[BLOCK_SIZE];
pBuffer = &BLOCK_MEM;

Even if this were right, would I still be able to use the array as normal, or would I have a bunch of issues?

LifeLong21
  • 15
  • 4
  • What is the error? – h0r53 Aug 07 '23 at 16:16
  • 3
    Both the initialization of `pBuffer` and the assignment on the next line seems very odd. What are you trying to do? – Some programmer dude Aug 07 '23 at 16:17
  • Also note that `&BLOCK_MEM` will have the type `int **`. That's not the type of `pBuffer`. – Some programmer dude Aug 07 '23 at 16:18
  • 2
    And please [don't cast the result of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Some programmer dude Aug 07 '23 at 16:18
  • 1
    `int *pBuffer = buffer;` which is equivalent to `int *pBuffer = &buffer[0];` @h0r53 – Barmar Aug 07 '23 at 16:21
  • 1
    Don't use `ALL_CAPS` names for variables. This is conventionally used for macros. – Barmar Aug 07 '23 at 16:22
  • Be consistent — sometimes you use `512`, sometimes you use `BLOCK_SIZE`; use `BLOCK_SIZE` everywhere except where you initialize it. – Jonathan Leffler Aug 07 '23 at 16:27
  • @h0r53: I think you mean `int *pBuffer = buffer;`, do you not? – Jonathan Leffler Aug 07 '23 at 16:28
  • `int *pBuffer = &buffer[BLOCK_SIZE];` will initialize `pBuffer` to point just past the last element of `buffer[];`. If you want it to point to the first element of `buffer[]`, initialize it as `int *pBuffer = buffer;` or `int *pBuffer = &buffer[0];`. `pBuffer = &BLOCK_MEM;` makes no sense as it is the wrong type. To make `pBuffer` point to the first `int` in the allocated memory pointed to by `BLOCK_MEM`, use `pBuffer = BLOCK_MEM;` or `pBuffer = &BLOCK_MEM[0];`. – Ian Abbott Aug 07 '23 at 16:32
  • 1
    What are you trying to do??? – ikegami Aug 07 '23 at 16:32
  • OK, so you have an actual array (`buffer`), and you have a dynamically allocated block of memory (pointed to by `BLOCK_MEM` if the `malloc` call returned a non-null value) that can be indexed like an array, and you have a pointer that can point to any integer and that can be indexed like an array if those indexed elements are contained within (or just past the end of) an array or within (or just past the end of) a dynamically allocated block of memory, or if the pointer is pointing to a non-array `int` and the index is 0 or 1 (and not accessing past the end). But what are you trying to do? – Ian Abbott Aug 07 '23 at 16:43

2 Answers2

2
const int BLOCK_SIZE = 512;
int *BLOCK_MEM = (int *)malloc(sizeof(int) * 512);

Here you define a named constant with value 512 but then use a literal 512. If these are supposed to be the same thing, use the named constant. If they are supposed to be different, define a second named constant and add a comment explaining why two different values are needed.

In C, unlike C++, it is not recommended to cast a call to malloc because it can suppress certain error messages. Also, it is recommended to use sizeof *p, where p is the pointer being assigned or initialized, instead of sizeof (type), because the former automatically adapts if the type of p is later changed, whereas the latter requires that the type be changed in two places. (So it is less work to change the former and less likely a human will mistakenly miss the fact they need to make the change in multiple places.)

So that line would become int *BLOCK_MEM = malloc(sizeof *BLOCK_MEM * BLOCK_SIZE);.

int *pBuffer = &buffer[BLOCK_SIZE];

This initializes pBuffer to point to end of buffer, specifically to a place one beyond the last element of pBuffer. That is probably not what you want to do. To initialize pBuffer to point to the start of buffer, you could use int *pBuffer = &buffer[0];. However, you could also use int *pBuffer = buffer;, because the array buffer will automatically be converted to a pointer to its first element when used this way.

pBuffer = &BLOCK_MEM;

This does not make sense with the previous line. int *pBuffer = &buffer[BLOCK_SIZE]; initializes pBuffer and then pBuffer = &BLOCK_MEM; immediately changes it, so the initialization had no effect. You should simply initialize pBuffer to the value you want it to have. And, if pBuffer is going to point to the allocated memory, you do not need to define buffer at all, unless you need it for some other purpose.

Additionally, the types are wrong in this assignment. BLOCK_MEM is a pointer to int, so &BLOCK_MEM is a pointer to a pointer to an int (type int **). But pBuffer is a pointer to an int (type int *). So the compiler issues a message that this assignment has a problem.

To set pBuffer to point to where BLOCK_MEM points, use pBuffer = BLOCK_MEM;.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
1

All you need is

const int BLOCK_SIZE = 512;

int *pBuffer = malloc( sizeof( int ) * BLOCK_SIZE );

Well, not quite. You might want to check the result of malloc to make sure it's not NULL.

if ( !pBuffer ) {
   perrror( "malloc" );
   exit( EXIT_FAILURE );
}

I still be able to use the array as normal

Well, you have a pointer, not an array. But virtually every time you use an array, it degrades into a pointer to its first element. (For example, a[4]*( a + 4 )*( &a[0] + 4 )). So yeah, you can use the pointer as an array. (Meaning p[4] will work just as well.) sizeof is the notable exception.

ikegami
  • 367,544
  • 15
  • 269
  • 518