Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++ - dynamically allocating memory to array of structs

  1. Sep 24, 2014 #1
    Let me start by saying I know this is a funky way to program, but my teacher is requiring us to go about it this way.

    also:
    I CANT use std::string, classes, constructors for this project.
    I am required to use this archaic method of c-style strings with dynamic memory allocation occuring outside the struct.. i know its not the best way to go about this, but theres nothign i can go. :(

    I have a struct
    struct card
    {
    char *suit;
    char *rank;
    int cvalue;
    }

    I've created a pointer of size 52 for my deck

    card *deckPtr = new card[52];
    card *deckHome = &deckPtr[0];
    I then try to use

    for(int i=0;i<52;i++)
    {
    (*deckPtr).suit = new char[8];
    (*deckPtr).rank = new char[7];
    deckPtr++
    }
    deckPtr=deckHome;

    I am essentially trying to fill in these arrays from a card file, but I cannot make it past running the program, i get sa seg fault which I dont understand why.

    I dynamically allocate memory in my card read in function..
    void cardInit(card *deckPtr)
    {
    card *deckHome = &deckPointer[0];
    ifstream fin;
    char *finName = new char[13];
    cin >> *finName
    fin.open(finName)
    .
    .
    .
    while(fin.good())
    {
    for(deckPointer=&deckHome[0];deckPointer<&deckHome[52];deckPointer++)
    {
    fin >> (*deckPointer).suit;
    fin >> (*deckPointer).rank;
    fin >> (*deckPointer).cvalue;
    }
    }



    Its a pretty simple program..and my dynamic memory works for the file name, but I cant figure out why it doesnt work for structs?
     
  2. jcsd
  3. Sep 24, 2014 #2

    Mark44

    Staff: Mentor

    After a cursory look at your code, I believe this line might be the source of your problem:
    Code (Text):
    for(deckPointer=&deckHome[0];deckPointer<&deckHome[52];deckPointer++)
    deckHome[52] is outside the array, so you shouldn't be trying to access it. The valid indexes for your array are 0 through 51.

    When you get the seg fault, is there a line number for the code where the fault occurs? Since this is a run-time error, probably not.

    If you're using a debugger, it should be fairly easy to spot where the error occurs. (You should be using a debugger...)

    As an alternative, put a print statement inside that loop that displays a count of the number of times the loop has run. If you get no output, then what I said above is very likely the problem.
     
  4. Sep 24, 2014 #3
    Code (Text):
    #include <iostream>
    #include <fstream>
    #include <ctime>
    #include <stdlib.h>
    #include <string>

    using namespace std;

    //global constant(s)
    const int maxCards = 52;

    //Structs
    struct card
      {
      char *suit;
      char *rank;
      int cvalue;
      char location;
      };

    //Function List
    void readPlayers(player *peoplePointer);
    void shuffleCards(card *unshuffled, card* shuffled);

    //program
    int main()
    {


    //create pointer and set initial value
    card * deckPointer = new card[52];
    card *deckHome = &deckPointer[0];
    for(int i=0;i<maxCards;i++)
    {
    (*deckPointer).suit=new char[8];
    (*deckPointer).rank = new char[7];
    deckPointer++;
    }
    deckPointer = deckHome;
    cardInit(deckPointer);
    readDeck(deckPointer);


    //sets default values for the card arrays
    for(int i=0;i<52;i++)
      {
     
      strcopy((*deckPointer).suit,"suit");
      strcopy((*deckPointer).rank,"rank");
      (*deckPointer).cvalue = 0;
      deckPointer++;
      }
    deckPointer = deckHome;
    return 0;
    }

    //Functions

    void cardInit(card *deckPointer)
    {
    card * deckHome = NULL;
    deckHome = &deckPointer[0];
    //set up card file to be read in
    ifstream fin;
    char *finName = new char[13];

    //get file name from user
    cout << "Enter file name...(cardFile.txt)" << endl;;
    cin >> *finName;


    //open the file
    fin.open(finName);


    //check if cardFile.txt opens correctly
    if(!fin.good())
      {
      cout << "Error with card file" << endl;

      }
    else
      {
      deckPointer = deckHome;
      while(fin.good())
      {
        for(int i=0;i<50;i++)
      {
      fin >> (*deckPointer).suit;
      fin >> (*deckPointer).rank;
      fin >> (*deckPointer).cvalue;
      deckPointer++;

      }
      }
      }
    delete [] finName;
    }
     
  5. Sep 24, 2014 #4

    Mark44

    Staff: Mentor

    Did that work? Or at least work better?

    I added [ code ] and [ /code ] tags around your code. We encourage people to use them to preserve any indentation they're using, which makes the code easier to read.
     
  6. Sep 24, 2014 #5
    my code only reads the "suit rank 0" 52 times instead of the correct "heart two 2" up to "spade ace 11"..

    so my code no longer seg faults, but something is wrong in my loop that copies the card..do you happen to have any insight to the problem?
     
  7. Sep 24, 2014 #6

    Mark44

    Staff: Mentor

    Code (Text):

    for(int i=0;i<52;i++)
    {
      strcopy((*deckPointer).suit,"suit");
      strcopy((*deckPointer).rank,"rank");
      (*deckPointer).cvalue = 0;
      deckPointer++;
    }
    I don't believe your code is reading "suit rank 0" 52 times. The loop above sets each member of your struct array to these values. If you're ending up with all members still set to the values as above, it looks like your code to read from the text file isn't working. When you get your code working, you can delete the loop above.

    If you're using a debugger, set a breakpoint in this loop (where you're reading from the input file) or add the line that I show with the comment:
    Code (Text):
    for(int i=0;i<50;i++)
    {
      printf("i is %d\n", i);  // Added line
      fin >> (*deckPointer).suit;
      fin >> (*deckPointer).rank;
      fin >> (*deckPointer).cvalue;
      deckPointer++;
    }
    The purpose of this is to see if suit, rank, and cvalue are getting set to the values in the input file.
     
  8. Sep 24, 2014 #7
    Thanks Mark! I figured out my issue!
     
  9. Sep 24, 2014 #8

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    His usage if fine. The 2003 version of the standard is not quite clear as it should be on whether these "one past the end" constructs are valid. It is very clear that deckPointer<deckHome+52 is without a doubt valid. Whether or not &deckHome[52] is valid depends on how nit-picky of a language lawyer one is. (Compare with the C99 standard, which explicitly makes it clear that both deckHome+52 and &deckHome[52] are valid.) The C++11 standard clarifies this: &deckHome[52] is valid.

    That said, whether a compiler is compliant with the standard is a different issue.
     
  10. Sep 24, 2014 #9

    Borek

    User Avatar

    Staff: Mentor

    Looks like I am missing something. Does &deckHome[52] count as accessing the element? Isn't it just asking for the address (in which case it shouldn't matter whether the object exists, as long as we don't try to use the address to access memory)?
     
  11. Sep 24, 2014 #10

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    The problem is the goofy way operator[] is defined in C and for primitive arrays in C++. The expression some_array[42] has always been defined as meaning *(some_array+42). One wonderful side effect of this definition is that the expression 42[some_array] is perfectly valid and means exactly the same thing as some_array[42]. Another wonderful side effect: &deckHome[52] means &*(deckHome+52). So is that "&*" a no-op, or does it mean something special?
     
  12. Sep 28, 2014 #11
    In C++, it might. If decHome is an object that declares operator[], the latter (ignoring the effects of optimization) will have to be called.

    I have been unable to find this clarification. Could you indicate which section of the std does that?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: C++ - dynamically allocating memory to array of structs
Loading...