0

I'm trying to make a simple database program, but when I get to this line

int idSearch(product* itens, int id) {
    int i = 0;
    for(i; i < size; i++) {
        if(itens[i].id == id) //<=== This line
            return i;
    }
    return ITEM_NOT_FOUND;
}

the program stops responding. size is set as a global variable in the begining of the program

FILE* flog;
FILE* db;
FILE* sizef;
int size = 100;

this function is called by

void newProduct(product* itens, char name[64], int id, float price) {
    int pos = idSearch(itens, 0);

    if(idSearch(itens, id) != ITEM_NOT_FOUND) {
        printf("Erro, o produto ja existe");
        return;
    }...

items is defined as

itens = (product*) calloc(sizeof(product), size); 

and product is a struct defined as such

typedef struct{
    char    name[64];
    int     id;
    float   price;
    int     amount;
} product;

Firstly I thought the problem was that I was not using the -> operator, but when I tried the compiler says its not right.

I'm using Code::Blocks with GCC compiler on a Windows 7 x64

**EDIT: the whole code can be found here: http://hastebin.com/atulajubar.tex

Hope to hear answers soon, Thanks in advance

21
  • Where is size defined in your first block of code? And what is it defined to? Commented Jul 7, 2014 at 23:56
  • size is defined as a global variable that was set to 100 in the main function. It was initialized as 0 though Commented Jul 7, 2014 at 23:58
  • Show the definition of itens ? That is, from where you passed it to newProduct ? Commented Jul 7, 2014 at 23:59
  • It's very difficult to tell from your code sample what the value is at the point of this function. Also, how was itens allocated? What size? Commented Jul 7, 2014 at 23:59
  • 1
    It is customary to pass the magnitude of one's array to any function that needs it. Don't rely on a global. Both newProduct and idSearch should have the proper size passed as an additional parameter. As written it is simply not possible to answer your question as you've given no reproducible steps, so guesses and speculation are the best you can hope for (and doesn't make for a good question, btw). My advise. lose the global size make it local to the creator of your array, and pass it along with the array base address as a param where needed. (and calloc is fine if used right). Commented Jul 8, 2014 at 0:12

2 Answers 2

2

**EDIT: You're calling calloc() wrong. The signature is: void *calloc(size_t nelem, size_t elsize); You're giving it the size first, then the number of elements. Switch that around and see if your problem is resolved.

Also, when calling (AFTER THE FIX:) itens = (product*) calloc( size, sizeof(product) );, it's important to check to see that itens is not NULL after doing this. If calloc isn't able to give you back the right amount of memory, it returns a NULL pointer I believe. Check this, because if you're getting NULL back, that's your issue.

One good, easy, portable way of checking that would be:

if(!itens){
   fprintf(stderr, "Error! Could not allocate memory!\n");
   exit(1);
}

Also, as WhozCraig suggested, please make sure your code contains #include <stdlib.h>, a requirement of calloc() as per its man page.

Sign up to request clarification or add additional context in comments.

14 Comments

I honestly doubt gcc compiled program will crash if buffer overflow.
@Kasama It more than likely means you have either freed the memory and/or are toting around an indeterminate pointer. printf("itens=%p\n", itens); immediately after the calloc() and likewise just inside your other functions may expose a junk pointer, but will not expose an incorrectly freed pointer. This app doesn't sound large. is there any chance at all you can simply post all the source to settle this once and for all?
@Kasama oh, and in since no on else bothered mentioning this, make sure <stdlib.h> is included (I will cackle big-time if that solves your issue, btw).
@Kasama see my edit again. You were/are calling calloc() with the wrong arguments - this is most likely at least one of your issues.
@Ricky Mutschlechner Yep. Thats why i suggested malloc. But noone seem'd to notice anything wrong with that calloc :D
|
1

This is wrong:

if((db = fopen(DB_PATH, RB))==NULL)
{
    if((db = fopen(DB_PATH, RWB))==NULL)
    {
        exit(1);
    }
    else
    {
        itens = (product*) calloc(sizeof(product), size);
        fwrite(itens, sizeof(product), size, db);
        rewind(db);
    }
}
fread(itens, sizeof(product), size, db);

If you have a DB_PATH file in the current working directory the first fopen() will succeed and the items allocation will never take place. Only if the file is not found, but is then successfully created will items contain a valid allocation, assuming calloc worked.

That else condition should be removed:

// note calloc parameter order addressed.
itens = calloc(size, sizeof(product));
if (itens == NULL)
{
    perror("Failed to allocate items.");
    exit(EXIT_FAILURE);
}

if((db = fopen(DB_PATH, RB))==NULL)
{
    if((db = fopen(DB_PATH, RWB))==NULL)
        exit(EXIT_FAILURE);

    fwrite(itens, sizeof(product), size, db);
    rewind(db);
}

fread(itens, sizeof(product), size, db);

There is a significant amount of error checking left to handle, but this needs to be addressed regardless.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.