C++ - dynamically allocating memory to array of structs

In summary: Please remove the tags when you're done.In summary, the author is trying to program in a archaic way that his teacher requires. They are having problems with a run-time error.
  • #1
mattskie
10
0
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 occurring outside the struct.. i know its not the best way to go about this, but there's 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 don't 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 can't figure out why it doesn't work for structs?
 
Technology news on Phys.org
  • #2
mattskie said:
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 occurring outside the struct.. i know its not the best way to go about this, but there's 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 don't 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 can't figure out why it doesn't work for structs?
After a cursory look at your code, I believe this line might be the source of your problem:
Code:
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.
 
  • #3
Code:
#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;
}
 
  • #4
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.
 
  • #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?
 
  • #6
Code:
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:
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.
 
  • #7
Thanks Mark! I figured out my issue!
 
  • #8
Mark44 said:
After a cursory look at your code, I believe this line might be the source of your problem:
Code:
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.
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.
 
  • #9
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)?
 
  • #10
Borek said:
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)?
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?
 
  • #11
Borek said:
Looks like I am missing something. Does &deckHome[52] count as accessing the element?

In C++, it might. If decHome is an object that declares operator[], the latter (ignoring the effects of optimization) will have to be called.

D H said:
The C++11 standard clarifies this: &deckHome[52] is valid.

I have been unable to find this clarification. Could you indicate which section of the std does that?
 

1. How do I dynamically allocate memory to an array of structs in C++?

To dynamically allocate memory to an array of structs in C++, you can use the new keyword followed by the data type and number of elements in the array. For example, structName* arrayName = new structName[10]; will allocate memory for an array of 10 structs.

2. How do I deallocate memory from an array of structs in C++?

To deallocate memory from an array of structs in C++, you can use the delete keyword followed by the name of the array. For example, delete[] arrayName; will free up the memory allocated for the array of structs.

3. Can I resize an array of structs in C++?

Yes, you can resize an array of structs in C++ by allocating a new array with the desired size and copying the elements from the old array to the new one. You can also use the realloc() function, but this is not recommended as it may lead to memory leaks.

4. How do I access elements in an array of structs in C++?

To access elements in an array of structs in C++, you can use the index notation. For example, arrayName[index] will return the element at the specified index in the array.

5. What are the advantages of using dynamically allocated arrays of structs in C++?

Using dynamically allocated arrays of structs in C++ allows for flexibility in the size of the array, as it can be resized as needed. It also allows for more efficient memory usage, as memory is only allocated for the elements that are needed. Additionally, it allows for easier manipulation of the data in the array compared to fixed-size arrays.

Similar threads

  • Programming and Computer Science
Replies
17
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
12
Views
2K
  • Programming and Computer Science
Replies
6
Views
2K
  • Programming and Computer Science
Replies
5
Views
884
  • Programming and Computer Science
Replies
4
Views
2K
  • Programming and Computer Science
Replies
8
Views
4K
  • Programming and Computer Science
3
Replies
89
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Programming and Computer Science
Replies
6
Views
5K
Back
Top