Seg fault Newbie

I am coming from java to c++ and I am trying to adjust to the nuances(more like huge differences). I am getting a seg fault error and can not figure out why. I have three files, unit_test1.cpp which holds my main(), card.cpp and card.h. I've been fight this for sometime now, any help would be greatly appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//card.h ---------------------------------------------------
#include <string>
#include <iostream>

class Card{
	public:
		Card();
		std::string getCard();

	private:
		std::string myCard;
};
//------------------------------------------------------------------

//card.cpp
#include "Card.h"
#include <iostream>

using namespace std;

Card::Card(){
	myCard  = "this is my card value - hearts";

}

string Card::getCard(){
	cout << myCard;
}

//--------------------------------------------------------------------------

//unit_test1.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "Card.h"

using namespace std;


int main(){
	
	Card *test;
		
	test = (Card *) malloc(sizeof(Card));
	test->getCard();
}
//------------------------------------------------------------------------
test = (Card *) malloc(sizeof(Card)); This allocates memory for Card. It does not creates instance of variable.

In Java it is something like
1
2
ByteBuffer cc = ByteBuffer.allocateDirect(/*Get size of card*/);
Card test = /*Somehow make it point to cc buffer*/;


In C++ you should use new for class dynamic allocation (allocalion and construction using malloc is possible, but unwieldy):
Card* test = new Card; //looks familiar, isn't it?

However in C++ you should prefer automatic variables instead:
1
2
Card test; //That's all. It is ready to use
test.getCard();
And if for some reason you need dynamic variables, consider using smart pointers:
1
2
3
std::unique_ptr<Card> test(new Card);
//or (C++14)
auto test = std::make_unique<Card>();
Smart pointers automatically delete corresponding variable when owner (all owners for shared pointers) is destoyed, saving yourself from hassle of manual memory management.
Thanks for helping, appreciate it.

I tried your suggestion but still getting a seg fault. The only code I changed was in unit_test1.cpp -
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//unit_test1.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include "Card.h"

using namespace std;


int main(){
	
	Card test;
	test.getCard();
}


I am currently working with bash so I am using c and c++. The lines are getting blurred, I suppose that is why I tried to use malloc instead of using automatic variables.
1
2
3
4
string Card::getCard()
{
    cout << myCard;
}
Here you declared getCard() as returning string, but did not return anything. It might lead to problems. Either declare it as void function, or actually return string:
1
2
3
4
5
6
7
8
9
10
const std::string& Card::getCard() //Return immutable reference to string (avoid copy)
{
    return myCard;
}
//...
int main()
{
    Card test;
    std::cout << test.getCard();
}


It looks like you did not enable warning in your compiler. I highly recommend to do so (as majority of errors can be fixed just by looking at warnings). Method of enabling warnings differs between different compilers/IDE, so say what you use if you will have any problems with that.
I changed something in your code and this is the result:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <string>
#include <iostream>

class Card{
	public:
		Card();
		std::string getCard();
		void printCard();

	private:
		std::string myCard;
};

Card::Card(){
	myCard  = "this is my card value - hearts";

}

std::string Card::getCard(){
	return myCard;
}

void Card::printCard() {
	std::cout << myCard << std::endl;
}


int main(){
	
	Card test;

	// two ways to print the card:
	test.printCard();
	// or
	std::string tmp = test.getCard();
	std::cout << tmp << std::endl;

	return 0;
}

No seg fault here.
Thanks that worked. I did as you said and applied a warning to my compile and it pointed out exactly that issue. I used -Wall, should I be using other warning flags when compiling.
Currently, Compile - g++ -Wall unit_test1.cpp Card.h Card.cpp
Add at least:
1
2
3
-Wextra /*Yes, GCC has own idea what -Wall means*/
-pedantic /*or preferably -pedantic-errors */
-std=c++11 /*or -std=c++1y to enable latest C++ standard. */
Added to my compile. Thanks again, I really needed that.
Additional note to MiiniPaa's response involving "new". Use "new" to allocate the Card pointer and "delete" to deallocate to the memory allocated by new. Without "delete" the memory won't be freed until the end of the program so in a more complex program with many allocations you will have a non-trivial memory leak.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

int main()
{
  // allocate Card and create instance
  Card* test = new Card;

  test->printCard();
  std::string tmp = test->getCard();
  std::cout << tmp << std::endl;

  // deallocate (C++ does not do automatic garbage collection like Java does)
  delete test;

  return 0;

}
Or use smart pointers instead :P
Topic archived. No new replies allowed.