I encountered a problem while initializing a pointer data member i.e int* apex; inside a constructor
having parameter as int i = 0; as *apex = i;
but unfortunately nothing is executed after compiler strikes this line.
#include <iostream>
using namespace std;
class base{
int *apex;
public:
explicit base(int i = 0){
cout << "this does executes" << endl;
*apex = i; // <<<<<--- problem???
cout << "this doesnt executes" << endl;
}
};
int main(void){
base test_object(7);
cout << "this also doesnt executes";
}
// I know how to avoid this but i want to know what
// exactly the problem is associated with *apex = i;
THANKS IN ADVANCE
note-no error is generated
What you wrote is equivalent to:
int *apex;
*apex = 42;
which is undefined behavior (UB), which includes that the compiler might just include code to stop execution or to start playing the song Never Gonna Give You Up by Rick Astley.
Even
int *apex = nullptr;
*apex = 42;
would be UB because the int* pointer has to point to a valid int when dereferencing via *
Just write
class base{
int apex{};
public:
explicit base(int i) : apex(i){}
};
And be done for
I got it. Trust me I am ashamed of myself after this silly doubt.
#include <iostream>
using namespace std;
class base{
int *apex;
public:
explicit base(int i = 0){
apex = new int;
// this is what i was supposed to do
*apex = i;
}
};
int main(void){
base test_object(7);
}
Your pointer points to invalid address you didn't initialize it
This will fix what you have asked to be done.
using namespace std;
class base{
int *apex{nullptr};
public:
explicit base(int& i ): apex{&i} {
cout << "this does executes" << endl;
cout << "this doesnt executes" << endl;
}
};
int main(void){
int a = 7
base test_object(a);
cout << "this also doesnt executes";
}
Make sure something (int) given to ctor has longer lifetime than an instance.
Related
See the below-given code
#include <iostream>
using namespace std;
class Number
{
int a;
public:
Number();
Number(int num_1) {
a = num_1;
}
void print_number(void) { cout << "Value of a is " << a << endl; }
};
int main()
{
Number num_1(33), num_3;
Number num_2(num_1);
num_2.print_number();
return 0;
}
In the above code, I am having 2 constructors in the same class but when compiling it,gives me the error
ccnd0o9C.o:xx.cpp:(.text+0x30): undefined reference to `Number::Number()'
collect2.exe: error: ld returned 1 exit status
Can anyone solve this problem? and I still need the 2 constructors but without replacing num_3 with num_3() the main function.
In your class, you have declared the default constructor, but you have not defined it.
You can default it (since C++11) and you will be good to go:
Number() = default;
Otherwise:
Number() {}
As from #TedLyngmo liked post, both will behave the same, but the class will get different meaning as per the standard, though. More reads here:
The new syntax "= default" in C++11
#Jarod42's Comment as side notes: The default constructor make sense when it provide a default value to the member a. Otherwise it will be uninitialized (indeterminate value) and reading them will cause to UB.
Use this code
#include <iostream>
using namespace std;
class Number
{
int a;
public:
Number(){};
Number(int num_1)
{
a = num_1;
}
void print_number(void) { cout << "Value of a is " << a << endl; }
};
int main()
{
Number num_1(33), num_3;
Number num_2(num_1);
num_2.print_number();
return 0;
}
How can such a code work correctly when the IWindow pointer clearly has an address to a ISheet class which has no method Say?
#include <iostream>
using namespace std;
class IWindow
{
private:
int p;
double f;
public:
void Say() { cout << "Say in IWindow"; }
};
class ISheet
{
public:
void foo() { cout << "ISheet::foo"; }
};
int main()
{
ISheet *sh = new ISheet();
int ptr = (int)sh;
IWindow *w = (IWindow*)ptr;
w->Say();
sh->foo();
return 0;
}
When compiled in Visual Studio 2015 it runs and executes with no problems, but I was expecting to get an error on line w->Say(). How is this possible?
It works by the grace of the almighty Undefined Behavior. Your functions don't try to access any data members of the containing class, they just write something to std::cout, which anyone can do.
What you've effectively done is
#include <iostream>
void IWindow_Say(void*)
{
std::cout << "Say in IWindow";
}
int main()
{
IWindow_Say(0xdeadbeef); // good luck with that pointer
}
You never used the pointer (which became this in your original example) so no side-effects were observed.
The code I'm working on :
I had the following code (with an error about the index in main.cpp) :
Sample.hpp :
#ifndef SAMPLE_HPP
# define SAMPLE_HPP
# include <iostream>
# include <string>
class Sample{
public:
Sample(void);
~Sample(void);
void tellname(void) const;
private:
std::string _name;
};
#endif
Sample.cpp :
#include <iostream>
#include "Sample.hpp"
Sample::Sample(void){
this->_name = "testname";
return;
};
Sample::~Sample(void){
return;
}
void Sample::tellname(void) const{
std::cout << "Name : " << this->_name << std::endl;
return;
}
main.cpp
#include "Sample.hpp"
int main(void){
int i;
Sample *test;
test = new Sample[4];
i = 0;
while (i++ < 4) // I know : i++; shouldn't be here
test[i].tellname();
delete [] test;
return 0;
}
If I compile this I get the following output :
Name : testname
Name : testname
Name : testname
Name :
My question is :
About the last line, it calls a method (void Sample::tellname(void)) but from an instance that is not in the range of the table (test[4] doesn't exist).
However, it still calls tellname() even the instance it calls it from doesn't exist. It just considers its _name field being empty.
How is this possible?
It's simply undefined behavior, something C++ imposes no requirements on so "anything could happen". What you're seeing is just a coincidence and worthless to reason about: next time you run it could crash, display nyan cat and so on.
It sounds like you are wondering why the function is called. In memory, structs do not contain the functions inside them. Instead, one copy of the functions are placed somewhere in the executable. So when you are calling test[4].tellname() what is really happening is: The address test + (4 * sizeof(Sample)) is passed to the function tellname(). The value at that address is undefined.
Here is an example to give you an idea of what is going on:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << '\n';
}
};
struct bstruct {
int y = 100;
};
int main()
{
bstruct b;
((astruct*)&b)->prnt();
getchar();
return 0;
}
Here prnt() is behind the scenes being passed the address of bstruct and treats it like the address of an astruct, since the first value in bstruct is 100, it prints 100. You can even simplify it to this:
#include <iostream>
struct astruct {
int i = 0;
void prnt()
{
std::cout << i << '\n';
}
};
int y = 100;
int main()
{
((astruct*)&y)->prnt();
getchar();
return 0;
}
i goes from 1 to 4 include, since tellname is const, test[4].tellname() is Sample::tellname with Sample being an undefined structure so "Name :" is rightfully printed then the memory in test[4]._name is printed and luckily the memory pointed by test[4]._name* is non null and is even a end string char.
So yeah you are lucky.
I have broken down my issue into a small simple program.
I have a class myclass I have created in a separate .cpp file "classes.cpp" and declared in the header file "classes.h". myclass contains a variable a of which is initialized when instantiated. This makes variable a = 5.
My overall goal is to create a class in a separate .cpp file declared in a .h file which I can create multiple instances of in my main() program. The problem I am having is this.
In my main() function I create an instance of myclass called first.
my main program shows the variable a is set to the number 5.
If I want to change that number using a static function (and it has to be a static function as this relates to something much bigger in another program I am writing). I call the static function directly and in that static_function I create an instance of myclass and call the non_static_function because static functions have no implicit 'this' connecting them to an object.
In my non_static_function I change the value to the number 8. The problem is that the value of variable 'a' in 'first' remains at 5 when I want it to be 8. I need to change the value using first->static_function(8) and not by first->a = 8. . How can I do this?
Code below:
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "the actual value of a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass::myclass()
{
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
cout << "The value for variable 'a' was 5 but is now: " << a << endl;
}
void myclass::static_function(int x)
{
myclass *p = new myclass();
p->non_static_function(x);
}
If you want every instance of myclass to have its own a and you want to call a static function to change it then you need to pass the instance you want changed to the static function. A static function can only modify static members of a class or the members of an instance that is inside its scope. Non static member functions can change any variable that is a member of the class.
class Foo
{
private:
int bar;
public:
static void static_function(int value, Foo & foo) { foo.bar = value; }
void non_static_function(int value) { bar = value; }
};
int main()
{
Foo foo;
Foo::static_function(8, foo);
// now bar will have the value of 8
foo.non_static_function(20);
// now bar will have the value of 20
}
I have finally found a way to deal with this small problem. Above the 'myclass' definition in classes.cpp I declare a 'myclass' variable
myclass *tgt; . Then in my constructor for 'myclass' I just allocate the instantiated object to a my global myclass variable of which I can access from the myclass definition tgt = this; Now I can use tgt in my static function to call the non_static_function in my 'myclass' definition and it all works perfectly.
NathanOliver, you are correct in saying that I need a class instance but the way I have done it here suits my needs. Passing the instance of myclass is certainly another way of doing this but it would require a global function above my 'myclass' definition.
Thanks for the help.
**main.cpp**
#include <iostream>
#include "classes.h"
using namespace std;
int main()
{
myclass *first = new myclass();
cout << "Myclass variable a is = " << first->a << endl;
first->non_static_function(8); // trying to change myclass variable 'a' to 8.
cout << "But" << endl;
cout << "The actual value of a is still: " << first->a << endl;
myclass *second = new myclass();
cout << "For the 'second' class the variable a is: " << second->a << endl;
second->non_static_function(23);
cout << "After calling the static function from 'second' the value of a is: " << second->a << endl;
cout << "And first->a is still: " << first->a << endl;
}
**classes.h**
#ifndef CLASSES_H_INCLUDED
#define CLASSES_H_INCLUDED
class myclass
{
public:
int a;
myclass();
void non_static_function(int x);
static void static_function(int x);
};
#endif // CLASSES_H_INCLUDED
**classes.cpp**
#include <iostream>
#include <cstdlib>
#include "classes.h"
using namespace std;
myclass *tgt; // *Add a global myclass variable above the myclass
definition*
myclass::myclass()
{
tgt = this; // *In the constructor allocate the instantiated class
//from main() to "tgt" .*
a = 5;
}
void myclass::non_static_function(int x)
{
a = x;
// Now see that the value of a is changed.
cout << "The value for variable 'a' was 5 but is now: "<< this->a << endl;
}
void myclass::static_function(int x)
{
tgt->non_static_function(x);
}
I'm getting a runtime error ("memory can't be written") that, after inspection through the debugger, leads to the warning in the tittle.
The headers are the following:
componente.h:
#ifndef COMPONENTE_H
#define COMPONENTE_H
using namespace std;
class componente
{
int num_piezas;
int codigo;
char* proovedor;
public:
componente();
componente(int a, int b, const char* c);
virtual ~componente();
virtual void print();
};
#endif // COMPONENTE_H
complement.h implementation
#include "Componente.h"
#include <string.h>
#include <iostream>
componente::componente()
{
num_piezas = 0;
codigo = 0;
strcpy(proovedor, "");
//ctor
}
componente::componente(int a = 0, int b = 0, const char* c = "")
{
num_piezas = a;
codigo = b;
strcpy(proovedor, "");
}
componente::~componente()
{
delete proovedor;//dtor
}
void componente::print()
{
cout << "Proovedor: " << proovedor << endl;
cout << "Piezas: " << num_piezas << endl;
cout << "Codigo: " << codigo << endl;
}
teclado.h
#ifndef TECLADO_H
#define TECLADO_H
#include "Componente.h"
class teclado : public componente
{
int teclas;
public:
teclado();
teclado(int a, int b, int c, char* d);
virtual ~teclado();
void print();
};
#endif // TECLADO_H
teclado.h implementation
#include "teclado.h"
#include <iostream>
teclado::teclado() : componente()
{
teclas = 0;//ctor
}
teclado::~teclado()
{
teclas = 0;//dtor
}
teclado::teclado(int a = 0, int b = 0, int c = 0, char* d = "") : componente(a,b,d)
{
teclas = c;
}
void teclado::print()
{
cout << "Teclas: " << teclas << endl;
}
The main method where I get the runtime error is the following:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
componente a; // here I have the breakpoint where I check this warning
a.print();
return 0;
}
BUT, if instead of creating an "componente" object, I create a "teclado" object, I don't get the runtime error. I STILL get the warning during debugging, but the program behaves as expected:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
teclado a;
a.print();
return 0;
}
This returns "Teclas = 0" plus the "Press any key..." thing.
Do you have any idea why the linker is having troube with this? It doesn't show up when I invoke the virtual function, but before, during construction.
Two errors that I can see:
strcpy(proovedor, ""); // No memory has been allocated to `proovedor` and
// it is uninitialised.
As it is uninitialised this could be overwriting anywhere in the process memory, so could be corrupting the virtual table.
You could change this to (in both constructors):
proovedor = strdup("");
Destructor uses incorrect delete on proovedor:
delete proovedor; // should be delete[] proovedor
As this is C++ you should considering using std::string instead of char*.
If you do not change to std::string then you need to either:
Implement a copy constructor and assignment operator as the default versions are incorrect if you have a member variable that is dynamically allocated, or
Make the copy constructor and assignment operator private to make it impossible for them to be used.
Another source of this same message is that gdb can get confused by not-yet-initialized variables. (This answers the question title, but not the OP's question, since a web search led me here looking for an answer.)
Naturally, you shouldn't have uninitialized variables, but in my case gdb attempts to show function local variables even before they are declared/initialized.
Today I'm stepping through another developer's gtest case and this message was getting dumped to output every time the debugger stopped. In this case, the variable in question was declared on ~line 245, but the function started on ~line 202. Every time I stopped the debugger between these lines, I received the message.
I worked around the issue by moving the variable declaration to the top of the function.
For reference, I am testing with gdb version 7.11.1 in QtCreator 4.1.0 and I compiled with g++ version 5.4.1