1

I am trying to create a function that takes in a array of structs as a parameter. This is part of my code so far:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MAXREAD 256
#define MAXARR 64
struct block {
  char free;
  bool end;
};


void display(struct block *b){
    char *p;
    printf("|");
    for(int i=0; i<MAXARR; i++){
        p = &b[i].free;
        //printf("%c ", *p);
        printf("%c", (*p != '\0' ? '#':'-'));
        //printf("%d", p);
        if(b[i].end){
            //printf("%d\n", i);
            printf("|");
        }
        //printf("%c", blocks[i]->end ? "true":"false");
    }
    printf("\n");
}
int main(){
    char input[MAXREAD];
    struct block (*blocks)[MAXARR];
    char cmd;
    int number;
    blocks = malloc(sizeof(struct block));
    char *a;
    //int *m;
    for(int i=0; i<MAXARR; i++){
      blocks[i]->free = '\0';
      blocks[i]->end = malloc(sizeof(bool));
      blocks[i]->end = false;
    }
    blocks[MAXARR-1]->end = true;
    display(blocks);
    while(strcmp(input, "q") != 0){
        printf("How many blocks do you want to allocate/free?\n");
        fgets(input, MAXREAD, stdin);
        a = strchr(input, '\n');
        *a = '\0';
        sscanf(input, "%c %d",&cmd, &number);
        if(strchr(input, 'q')){
            break;
        } else if(strchr(input, 'a')){
            alloc(number, blocks);
        } else if(strchr(input, 'f')){
            dealloc(number, blocks);
        }
        display(blocks);
    }
    exit(0);
}

When I compile the program, this warning shows up:

warning: incompatible pointer types passing 'struct block (*)[64]' to parameter of type 'struct block *' [-Wincompatible-pointer-types] display(blocks);

I looked into these two posts and tried it out but the warning keeps showing up regardless:

Passing an array of structs in C

How to pass an array of struct using pointer in c/c++?

can someone please explain to me what is wrong with my program?

Community
  • 1
  • 1
  • `struct block (*blocks)[MAXARR];`...hhmmmm – Sourav Ghosh Jul 21 '15 at 11:14
  • struct block (*blocks)[MAXARR]; this statement is understood as "blocks is a pointer to array of type struct block of MAXARR size".You need to change the signature of the display function to void display(struct block (*b)[]) or void display(struct block **b) – nikhil mehta Jul 21 '15 at 11:24
  • 1
    You declare `blocks` as an array of 64 pointers to `struct block`. Then you use `malloc` to allocate a block of memory equal to the size of one `struct block` and assign this to `blocks`. This is wrong. `blocks` is already allocated to the stack and has the size of 64 pointers. You should instead allocate a block of memory for each `block[i]` inside the for loop. This is not your only problem though. – axxis Jul 21 '15 at 11:29
  • 1) always check the returned value from malloc(), sscanf(), alloc(), dealloc(), fgets(), strchr() to assure the operation was successful. 2) the contents of the first char of 'input' is being checked for 'q' before any specific contents are placed into 'input'. BTW: alloc() and dealloc() are prototyped in alloc.h, which is missing from the code – user3629249 Jul 23 '15 at 14:26
  • when #define'ing a numeric value always wrap that value in parens to avoid text-replacement errors. For readability by us humans, please insert a blank line between code blocks. The code is searching 'input' for 'q' and comparing the first char for 'q' suggest using the 'cmd' variable. which contains the first char of the read in line of data. – user3629249 Jul 23 '15 at 14:32
  • the use of alloc and dealloc will result in memory leaks. suggest using realloc() -- and always check the returned value before assigning to 'blocks' – user3629249 Jul 23 '15 at 14:34
  • the alloc and dealloc of the blocks does not place any specific value into the block struct instances, so this line: 'if(b[i].end){' is checking the contents of an un-initialized field. This line: 'printf("%c", (*p != '\0' ? '#':'-'));' is checking the contents of an un-initialized field. – user3629249 Jul 23 '15 at 14:39

4 Answers4

5
struct block (*blocks)[MAXARR];

So, blocks is a pointer to an array of block's.

Then you called display() like :

display(blocks);

where, you defined display() as

void display(struct block *b)

which takes a block pointer only.

According to how you implement display(), here's some suggestion for you:

  1. Change void display(struct block *b) to void display(struct block *b[]) to print/access all elements blocks.

  2. Instead of . you need to use -> operator as b is a pointer to block.

  3. In main(), declare blocks as block *blocks[MAXARR]; which means an array of block pointers. Read this for more information.

  4. blocks = malloc(sizeof(struct block)); makes no sense. You need to malloc every block elements individually. Something like this:

    int i; for(i = 0; i< MAXARR; i++) { blocks[i] = (block *)malloc(sizeof(block)); }

  5. You do not need to blocks[i]->end = malloc(sizeof(bool));.

After all these, you can call display(blocks);.

Community
  • 1
  • 1
mazhar islam
  • 5,561
  • 3
  • 20
  • 41
  • after all the calls to malloc(), before exiting the program, need to pass each pointer from malloc() to free() to avoid memory leaks. – user3629249 Jul 23 '15 at 14:15
2
struct block (*blocks)[MAXARR];

This is causing problem as it creates a pointer to array of struct block. Whereas your function requires a pointer to struct block.

void display(struct block *b);

Therefore,it gives error.

struct block *b;

Will be correct statement.

mazhar islam
  • 5,561
  • 3
  • 20
  • 41
ameyCU
  • 16,489
  • 2
  • 26
  • 41
  • 1
    @NewbieProgrammer, you sure _it worked_? Your implementation of `display()` say something else. – mazhar islam Jul 21 '15 at 11:50
  • @rakeb.void I was wondering the same. There are so many errors in this code, it's impossible it worked just with this change. – axxis Jul 21 '15 at 11:57
  • @axxis, Yes the code will never gonna work unless OP changes a lot. – mazhar islam Jul 21 '15 at 12:06
  • 1
    @rakeb.void Yes, it wont even compile I just pointed particular error . – ameyCU Jul 21 '15 at 12:08
  • @ameyCU, but the solution you pointed out is not actually correct because OP tries to display all `blocks` (implementation says so). But your approach can remove the warning! Cheers! – mazhar islam Jul 21 '15 at 12:11
0

Define this:

struct block * blocks;

instead of struct block (*blocks)[MAXARR].

i486
  • 6,491
  • 4
  • 24
  • 41
-1

I think the explicit type-casting to struct pointer is needed while assigning memory dynamically. blocks = (struct block *) malloc(sizeof(struct block));

Jaydeep Ranipa
  • 421
  • 5
  • 16