-2

I want to create an array of struct pointers and set each pointer to null. Eventually I want to have the pointers in the array point to my struct. I believed I had the write code to this but I keep getting a seg fault.

Code:

//struct in my .h
struct bin{
 double cac; // current available capacity
 struct node *list //pointer to linked list... bin struct points to linked list struct
}
//main file
void main(){
 struct bin *bArray[20];
 struct bin *binTemp, *pTemp;
 for(i=0;i<20;i++) bArray[i]= NULL;
}

I assumed this would create an array of bin pointers, but I'm getting a seg fault here. Shouldn't I be able to make all the pointers NULL regardless of what type of pointer they are?

Eventually I want to make these all point to bin structs and I thought I could do this without having to make the pointers NULL first so i tried:

for(i=0;i<20;i++){
  binTemp = (struct bin *)malloc(sizeof(struct bin));
    binTemp->cac = 1.0;
    binTemp->list = NULL;
    bArray[i] = binTemp;
}   

Once again I got a seg fault. I have no idea whats going on here. I know seg faults means I'm trying to write to an illegal memory location which makes me think I would have to set the size of the array indexes with malloc. However,

for(i=0;i<20;i++) bArray[i]= malloc(sizeof(struct bin));

also gives me a seg fault. I have no idea what I'm doing wrong.

Actual code I ran:

//Header File

#ifndef hBin_h
#define hBin_h

#include <stdio.h> // stdio used for file io
#include <stdlib.h> // standard c library 

#define MAX_S 20


//bin struc
struct bin {
    double cac; //current available capacity
    struct node *list; // pointer to linked list
};
//linked list node struct
struct node{
    char *name; //name of item
    double size; // weight of item
    struct node *next; //pointer to next
};

//insert the new item into a node in its appropriate location using alphabetical ordering of item names
struct node *oInsert(char *item, double size, struct node *head);
//print the items of the list out along with the list’s capacity
void traverse(struct node *head);
// deallocate the nodes of the list
void destory(struct node *head);
//input info from file - name of object, weight of object
void input(FILE *inFile, char item[], double *weight);

#endif // hBin_h

#include "hBin.h"



void main(){
  FILE *inFile;
  char *item;
  double *weight;
  struct bin *bArray[20];
  int i;

  struct bin *binTemp, *pTemp;


  inFile = fopen("run1.txt", "r"); //open file
  printf("HERE1\n");

  for(i=0;i<20;i++){
      binTemp = (struct bin *)malloc(sizeof(struct bin));
      binTemp->cac = 1.0;
      binTemp->list = NULL;
      bArray[i] = binTemp;
  }   


/*while(!feof(inFile)){
input(inFile, item, weight);
printf("%s, %.2f\n", item, *weight);
}*/
}

I used gdb (not totally sure what I'm doing here):

(gdb) run
Starting program: /home/Christopher/CSC362/Pass_F/Main
[New Thread 813244.0xc7590]
[New Thread 813244.0xc6ce0]
[New Thread 813244.0xc7320]
[New Thread 813244.0xc5994]
HERE1
      0 [main] Main 813244 cygwin_exception::open_stackdumpfile: Dumping stack trace to Main.exe.stackdump
[Thread 813244.0xc7320 exited with code 35584]
[Thread 813244.0xc6ce0 exited with code 35584]
[Inferior 1 (process 813244) exited with code 0105400]
(gdb) where
No stack.
(gdb) for(i=0;i<20;i++){
    binTemp->cac = 1.0;
    binTemp->list = NULL;
    bArray[i] = binTemp;
}   /usr/src/debug/cygwin-2.2.1-1/winsup/cygwin/crt0.c: No such file or     directory.
(gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
Undefined command: "binTemp".  Try "help".
(gdb)     binTemp->cac = 1.0;
Undefined command: "binTemp->cac".  Try "help".
(gdb)     binTemp->list = NULL;
Undefined command: "binTemp->list".  Try "help".
(gdb)     bArray[i] = binTemp;
Undefined command: "bArray".  Try "help".
(gdb) }   for(i=0;i<20;i++){
Undefined command: "".  Try "help".
(gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
Undefined command: "binTemp".  Try "help".
(gdb)     binTemp->cac = 1.0;
 Undefined command: "binTemp->cac".  Try "help".
 (gdb)     binTemp->list = NULL;
 Undefined command: "binTemp->list".  Try "help".
 (gdb)     bArray[i] = binTemp;
 Undefined command: "bArray".  Try "help".
 (gdb) }   for(i=0;i<20;i++){
 binTemp->cac = 1.0;
 Undefined command: "".  Try "help".
 (gdb)   binTemp = (struct bin *)malloc(sizeof(struct bin));
 Undefined command: "binTemp".  Try "help".
 (gdb)     binTemp->cac = 1.0;
 Undefined command: "binTemp->cac".  Try "help".
 (gdb)     binTemp->list = NULL;
 Undefined command: "binTemp->list".  Try "help".
 (gdb)     bArray[i] = binTemp;
 Undefined command: "bArray".  Try "help".
CinCity
  • 149
  • 2
  • 10
  • Please post the code that actually crashes, see [MCVE](http://stackoverflow.com/help/mcve) – Weather Vane Dec 03 '15 at 12:01
  • 1
    If `bArray` or `binTemp` are declared as you show in the first code snippet, then none of the code snippets you show should give you segmentation faults. Please run the crashing program in a debugger to locate the crash, where it happens in your code, and look at the involved variables to see if any of them look wrong. Oh, and *please* try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us. – Some programmer dude Dec 03 '15 at 12:01
  • 3
    By the way, the middle example, where you cast the result of `malloc`, could actually lead to undefined behavior and crashes if you do not include the correct header file. See ["Do I cast the result of malloc?"](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) for more information. – Some programmer dude Dec 03 '15 at 12:04
  • 2
    It is not. It does not compile, for one thing, and has no `#include` statements for another, and, it does not crash as given. The problem lies in code you have not posted. – Weather Vane Dec 03 '15 at 12:16
  • 1
    @CinCity I assume you tried to add the code in the comment? Don't do that! It won't be formatted and will be basically unreadable. Instead *edit your question* to include crucial and relevant information. – Some programmer dude Dec 03 '15 at 12:18
  • updated the question - updated again to show .h – CinCity Dec 03 '15 at 12:19
  • The program you added doesn't crash, at least not if that's the program you used in GDB, it runs from start to end, which means the crash happens somewhere else in your actual program. There are some things you should look at though, first of all is the casting of the result of `malloc` that I mentioned above. You also don't check if `malloc` succeeded or not, as well as checking if the `fopen` call succeeded or not. Finally, read about ["Why is “while ( !feof (file) )” always wrong?"](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Some programmer dude Dec 03 '15 at 12:25
  • Sorry, still does not crash. Perhaps the problem is in the commented-out `input(inFile, item, weight);` where you either pass uninitialised variables, or intended to pass their *address*. BTW that's the wrong way to use `feof()`, please see [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Weather Vane Dec 03 '15 at 12:26
  • I got rid of that part of the code and it compiled, but that part of the code worked earlier. – CinCity Dec 03 '15 at 12:29
  • In this line `printf("%s, %.2f\n", item, *weight);` neither of the arguments have been initialised, so you'll get undefined behaviour. – Weather Vane Dec 03 '15 at 12:33
  • so change them to *weight = NULL; item = " "; – CinCity Dec 03 '15 at 12:34
  • `*item` and `*weight` are pointers. The first needs to point to a nul-terminated array of `char` and the second needs to point to a `double`. – Weather Vane Dec 03 '15 at 12:35
  • Since your latest code update: no runtime error here, although there are some compiler warnings (for example the signature of `main()`. I feel we still are not getting the full story, since you prototype 4 functions which you don't *appear* to be using. – Weather Vane Dec 03 '15 at 12:41

1 Answers1

1

Reading your code you commented out, you pass the variable weight to the input function and right after dereference it in your call to printf. There is a major problem here, and that is that the variable weight is not initialized, and that passing it to a function passes it by value, which means that the variable is copied and the function only operates on the copy and not the original, meaning that the weight variable in your main function will still be uninitialized when you dereference it and that leads to undefined behavior and a probable crash.

If you intend to emulate pass by reference (you can only emulate since C doesn't have passing by reference), you should declare weight as a normal variable, and use the address-of operator when calling the function:

double weight;

...

input(inFile, item, &weight);
//                  ^
//                  |
// Note ampersand here

You have a similar problem with the item variable. It's uninitialized and doesn't point anywhere special. Using it in any way except to initialize it will lead to undefined behavior. And if you try to initialize it in the input function then you have the same problem as described above, and you need to pass a pointer to the pointer using the address-of operator.

If you don't initialize the item pointer in the input function, but use it like it's already pointing to some valid memory (using e.g. strcpy or similar function) then you also have undefined behavior.


The actual crash you experience might be totally unrelated to the problems I describe above, since you seem to be doing something involving linked lists, which of course means pointers, and pointers used wrongly will give you many chances for further undefined behaviors and crashes.

The first thing you should do is enable more warning when building, as the compiler is usually very good at finding suspect behavior that can lead to UB. You do that by adding e.g. the flags -Wall -Wextra -pedantic when building.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • `void input(FILE *inFile, char item[], double *weight){ fscanf(inFile, "%s %lf", item, weight); //scan info from text file }` this is my input function. When I put it above the for loop for the bin structs it works fine, but if I put if after the bin struct for loop I get a seg fault again. – CinCity Dec 03 '15 at 12:39
  • @CinCity That function will give you undefined behavior no matter when and where you call it, if you use those uninitialized pointers. The important thing to remember about undefined behavior is that sometimes it might *seem* to work fine (but in reality does something wrong, like writing to unknown memory locations). – Some programmer dude Dec 03 '15 at 12:42
  • so I should do something like `double weight = 0; for (int i=0; i<20; i++) item[i]='\0';` – CinCity Dec 03 '15 at 12:47
  • @CinCity No, you should do something like `char item[256];` – Some programmer dude Dec 03 '15 at 13:19