Im having this really weird error during run-time.
My program takes two parameters, does some math calculus with them and std::cout's the values in the end.
My program works if i input somevalues, but if i input other values it says that a variable is being used without being initialized, which i think it makes no sence.
Here is the code:
#include <iostream>
#include <stdio.h>
#include <cmath>
double align_nb(int n) { return { ceil(n / 512.0)*512.0 }; } // bytes
double align_pt(int k) { return { floor(k / 512.0)*512.0 }; } // pointer
int main(int argc, char * argv[])
{
int o_n = std::atoi(argv[1]); // original number
int o_p = std::atoi(argv[2]); // original pointer
int max_bytes, new_pointer; // max bytes to read, new pointer to point
float log = (std::log(o_n) / std::log(2));
if (log != floor(log))
{
max_bytes = align_nb(o_n); // bytes alinhados para a frente
new_pointer = align_pt(o_p); // ponteiro alinhado atrĂ¡s
}
else if (log == floor(log))
{
new_pointer = align_pt(o_p);
if (max_bytes + (o_p - new_pointer) >max_bytes)
{
max_bytes += 512;
}
}
std::cout << "Original bytes= " << o_n << std::endl;
std::cout << "Original pointer= " << o_p << std::endl;
std::cout << "Max_bytes= " << max_bytes << std::endl;
std::cout << "new_pointer= " << new_pointer << std::endl;
return 0;
}
Here are the values i tested it and it crashed, giving me that run-time error:
2048 513
1024 500
here is one example of values were the code doesnt give me that error and the program works:
513 520
Here is a print of the error it gives me.
I'd really appreciate someone explaining me why it gives me that error/how to fix it.
Regardless, thanks!
(PS: math tag is included cause it could be the math in the program that is causing it to crash. If annyone thinks it shoudlnt be used in this question, let me know in the comments and ill remove it.)
(PS 2: the variable it complains when it gives me the run time error is 'max_bytes'.)
If your code takes the else path at line 17, then your code doesn't initialize max_bytes, but uses it afterwards. That's the problem.
Notes:
comparing calculated floating point values for equality usually a bad practice
you don't need the additional if at line 23.
Make sure that for each path your code takes the values of the variables you use are initialized. If you don't you get what is called Undefined Behaviour. There could be anything in an uninitialized variable.
int max_bytes;
....
....
expression_involving_max_byte <- Dangerous!
Related
I'm writing a short program to convert a string (consisting of numbers) to an integer. The code runs ok but I keep getting an odd intellisense error on the "int" part of the int main() declaration. The error text is: this declaration has no storage class or type specifier
and shows the first two letters (the "in") in white and the last (the "t") in the yellow that recognized function names are usually tagged with.
Does anyone know what this might be? Is it just an intellisense anomaly or is there something wrong with my code?
Here's the full code listing:
#include <iostream>
#include <string>
int stringConvert(std::string);
int main()
{
std::string str("123");
int stringNum = stringConvert(str);
std::cout << str << " --> " << stringNum << std::endl;
return 0;
}
int stringConvert(std::string stringIn)
{
int n = std::stoi(stringIn);
std::cout << "String conversion completed" << std::endl;
return n;
}
The objective of this program is of right now to set each array variable of the 2D array,
char mass_data_shift[9][9]; equal to 'T' . Which should equal 100 Ts overall.
This is done by calling a void function with this 2D array address as an argument. Calling it by a pointer to then be initialized in a loop.
Inside the loop is were the 2D array should be set to T.
*mass_data[mass_data_counter][mass_data_counter_two] = 'T';
However..... the program results in:
(Most Often) A Segmentation Fault after trying to initialize *mass_data[4][2]
(Sometimes) A Segmentation Fault after the program successfully(?) runs.
(Sometimes) The program successfully runs.
Meaning the program, somewhere, is writing out of bounds. Any help would be appreciated in both making the program run without a segmentation fault and/or fixing other mistakes.
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
void mass_data_define(char (*mass_data)[9][9]){
int mass_data_counter;
int mass_data_counter_two = 0;
for (mass_data_counter=0;mass_data_counter<9;mass_data_counter++){
do {
std::cout << "|Array #1 " << mass_data_counter
<< " ::: |Array #2 " << mass_data_counter_two
<< std::endl;
*mass_data[mass_data_counter][mass_data_counter_two] = 'T';
std::cout << *mass_data[mass_data_counter][mass_data_counter_two];
mass_data_counter_two++;
std::cout << "---------End of Counter 2 Init Code----------" << std::endl;
} while (mass_data_counter_two < 9);
mass_data_counter_two = 0;
}
}
int main()
{
char mass_data_shift[9][9];
mass_data_define(&mass_data_shift);
std::cout << "-END-" << std::endl;
return 0;
}
Final Edit: The main cause was solved by szym below. Sorry about the whitespaces and missing iostream , was a formatting issue when I made the post. Also changed the loop to fit the array length as suggested below.
*mass_data[mass_data_counter][mass_data_counter_two] = 'T';
Should be
(*mass_data)[mass_data_counter][mass_data_counter_two] = 'T';
Naturally, same goes for the line:
std::cout << *mass_data[mass_data_counter][mass_data_counter_two]
But really this pointer type is not necessary to pass array by reference in C/C++.
You should instead declare:
void mass_data_define(char mass_data[9][9]) {
// To read:
char z = mass_data[3][6];
// To write:
mass_data[2][1] = 'C';
}
// elsewhere
char my_mass_data[9][9];
mass_data_define(my_mass_data);
Short Answer: Here's a one-line fix to your code so may continue to use a pointer and still not get a segmentation fault:
(*mass_data)[mass_data_counter][mass_data_counter_two] = 'T';
Long Answer: Read Create a pointer to two-dimensional array.
For an in-depth understanding of how to pointers to access multi-dimensional arrays, read this.
I need to keep some information about each function in my program in the form of a constant number. I was wondering if it is possible to put the constant for a function just before it in the code memory, so if a function is called through a function pointer, that information could be read by subtracting the value of the function pointer.
To illustrate further, my code memory should look as follows.
ConstantForFunc1
Func1:
....
ConstantForFunc2
Func2:
....
And following is an example code of how I would read that information
FuncPointer f = &Func2;
int constantForFunc2 = *((int*)(f - sizeof(int)));
And note that using Hash tables is too slow for what I'm trying to achieve, so I need a very fast method. And all this modification, which is inserting constants and code to read from them is done by a compiler pass, which I'm writing and which modifies the LLVM IR. Using structures would be too cumbersome for the compiler pass, as it would have to modify a lot of code.
What you are doing doesn't make sense, yet:
You could use structs maybe?
struct example
{
int constantForFunc;
void (*ptrToFunc)();
};
//After declaring, maybe 3, functions
struct example funcList[3] = {{5, &func1}, {10, &func2}, {15, &func3}};
int currentFuncConstant=funcList[1].constantForFunc;
(*funcList[1].ptrToFunc)();
I haven't used function pointers to be honest, probaby has mistakes.
Is this not acceptable at all?:
#include <iostream>
using namespace std;
const int Const__Fxn1 = 1;
void Fxn1()
{
cout << "Fxn1" << endl;
}
const int Const__Fxn2 = 2;
void Fxn2()
{
cout << "Fxn2" << endl;
}
#define GetFxnConst(FxnName) Const__ ## FxnName
int main()
{
cout << GetFxnConst(Fxn1) << endl;
cout << GetFxnConst(Fxn2) << endl;
return 0;
}
Option 2:
#include <iostream>
#include <cstring>
using namespace std;
const volatile int v1 = 0;
volatile unsigned v2 = 0;
void Fxn1()
{
if (v1) { v2 = 0x12345601; }
cout << "Fxn1" << endl;
}
void Fxn2()
{
if (v1) { v2 = 0x12345602; }
cout << "Fxn2" << endl;
}
int FindFxnConst(void(*f)())
{
const unsigned char* p = (const unsigned char*)f;
while (memcmp(p, "\x56\x34\x12", 3))
p++;
return p[-1];
}
int main()
{
Fxn1();
cout << FindFxnConst(Fxn1) << endl;
Fxn2();
cout << FindFxnConst(Fxn2) << endl;
return 0;
}
Output (Ideone):
Fxn1
1
Fxn2
2
You can embed more than 8 bits of data per function by using other magic prefixes, e.g.:
if (v1)
{
v2 = 0x12345611; // byte 1
v2 = 0x789ABC22; // byte 2
v2 = 0xDEF01233; // byte 3
v2 = 0xFEDCBA44; // byte 4
}
This is not necessarily a reliable solution, let alone portable.
Since the addresses of the functions are known from the executable binary (unless they are loaded from a shared library ofcourse), if you have the address space layout randomization (ASLR) off, you could use gperf to generate a highly efficient hash function for you and use that hash function to get the constants for each function.
However, for this, you will have to compile your program twice, first to get the addresses of the functions from the generated binary, so that you could give those addresses as an input to gperf and recompile using the hash function generated by gperf. But you have to be careful that the addresses of the functions from the first compilation do not become different in the second compilation. I am not sure, how to achieve that.
An alternative, would be to do something like gperf just after your program is loaded, so you don't have to compile twice. But I don't know how to do that.
I'm using the finite element library for some calculations, and I've encountered a bizarre problem.
I basically have the following for loop:
MeshBase::const_node_iterator node_it = mesh.nodes_begin();
for (unsigned int i=0;i<n_nodes;i++ , node_it++){
const Node* node2 = *node_it;
Point dumpoint( (*node2)(0), (*node2)(1), (*node2)(2));
Number dumreal= (Number) mesh_data.get_data(node2)[0];
// std::cout << dumreal <<std::endl;
dummap[dumpoint] = mesh_data.get_data(node2)[0];
}
If I uncomment the line with cout, it works. Otherwise I get a segfault. It doesn't matter what I print:
std::cout << std::endl;
An important note is that dummap is a global
std::map<Point,Number>
Using valgrind showed that the problem was with some char* array I allocated somewhere else.
Thanks ^^
I recently wrote a program to help me understand the basics of memory pointers in C++, I chose a simple prime number finder.
I finally got it to work. (yay for debugging!)
And I let it run to see how far it goes, it gets to prime #815389 with my verbose tells me is the 65076th prime, I get an app crash. The one thing I could think of was my ints overflowing so I changed them to longs, it gets stuck at the same place.
Would someone be able to help explain what limitation is causing this?
comp: WinVista 64-bit Home Premium, 6GB ram AMD 4800+ X2
program crashes at 4,664K memory usage
Source:
#include <cstdlib>
#include <iostream>
\\\\(Backslashes added for readability)
using namespace std;
long number;
long numnum;
class num;
class num {
public:
long i;
void check();
bool nxt;
num* nxtnum;
};
void num::check() {
if (number % i != 0) {
if (nxt == true) {
(*nxtnum).check();
} else {
nxtnum = new num();
(*nxtnum).i = number;
numnum++;
cout << numnum << ":" << number << ", ";
nxt = true;
};
};
};
int main(long argc, char *argv[]){
numnum = 1;
cout << numnum << ":" << 2 << ", ";
num two;
two.i = 2;
for (number = 3; 1<=1000001; number++) {
two.check();
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
(Nevermind the username it's just an alias I use so I can keep track of all my posts with google)
Stack overflow? I see that check is recursive.
I'd put a guess on the fact that two.nxt isn't initialized. In C, primitive datatypes aren't initialized, meaning they have the value of whatever happened to be in whatever memory it's now occupying. That means that more than likely, in main(), two.nxt = true, which causes check() to be run on an invalid pointer. Try explicitly setting it to false and see if that works for you.
[edit] If this is the issue, the more important initialization would be when you allocate the new num in check().
Sean is right, two.nxt is never initialised. In fact, num.nxt is never initialised for any instance of num. The member nxt is unnecessary if the class is made more robust. The nxt pointer can be used instead:
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void check ()
{
if (number % i != 0)
{
if (nxtnum)
{
nxtnum->check ();
}
else
{
nxtnum = new num (number);
cout << ++numnum << ":" << number << ", ";
}
}
};
Of course, the recursive nature is probably the main culprit, the initialisation issue was hidden as you were probably running a debug build. Converting the recursive form to the iterative form is left as an exercise.
Couple of problems I can see:
You're allocating a bunch of nums, but you're not checking for a std::bad_alloc exception. You might simply be running out of memory...
You're not checking anywhere if nxtnum is != 0, even though I think it's safe to do so as the only places where you dereference it are guarding. Nevertheless, it's not that great a practise.
As Sean Edwards mentions, the num class doesn't have a constructor, so the members of a newly created num are filled with pretty much random junk. And that random junk might include nxt being set to a nonzero value. I'd add the following constructor to give it a set of safe defaults:
num::num() : i(0), nxt(false), nxtnum(0) {}
You don't really need the boolean value, I'd just check for nxtnum being non-zero.
As Jeff Yates says, you might suffer from a stack overflow as the recursive function is getting nested too deep, but it doesn't look like it'll recurse that deep.
Incidentally, if you're using a Microsoft compiler, int and long are the same size when targeting x64. You also have an infinite loop in your main function, as 1 will always be <= 1000001.
I've got it working, thank you Skizz
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
long number;
long numnum;
class num;
num *two;
num *nn;
num *bre;
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void *check ()
{
if (number % i != 0)
{
if (nxtnum)
{
//nxtnum->check ();
nn = nxtnum;
}
else
{
nxtnum = new num(number);
cout << ++numnum << ":" << number << ", ";
nn = bre;
}
}else{nn=bre;}
}
};
int main(long argc, char *argv[])
{
numnum = 1;
cout << numnum << ":" << 2 << ", ";
two = new num(2);
nn=two;
for (number = 3; 1<=1000001; number++) {
while (nn!=bre){
nn->check();
Sleep(0);
}
nn=two;
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
For Those Interested