The problem is that, when I set a breakpoint at the line of the #include, gdb just ignore the line and stop at the next instruction in the main (I compiled the main.cpp with g++ -g -O2 -std=c++11).
The program works perfect (-O2 doesn't affect the result at all), but I want to check what exactly does something inside that file, but I can't because gdb doesn't let me enter the code inside the file.
How can I debug code inside other file? Is it even possible?
Edit: Here is the code
main.cpp
#include <iostream>
#include <cstdlib>
#include <chrono>
#include "inc/includes.h"
template <class T>
void PrintVector(T* vector, int size){
for (int i=0; i<size; ++i){
std::cout << vector[i] << " ";
}
std::cout << std::endl;
}
template <class T>
void CheckTime(void (*f)(T*&, int), T* &vector, int size){
std::chrono::high_resolution_clock::time_point tantes, tdespues;
std::chrono::duration<double> transcurrido;
tantes = std::chrono::high_resolution_clock::now();
(*f)(vector, size);
tdespues = std::chrono::high_resolution_clock::now();
transcurrido = std::chrono::duration_cast<std::chrono::duration<double>(tdespues - tantes);
std::cout << size << " " << transcurrido.count() << std::endl;
}
int main(int argc, char * argv[]){
if (argc != 2){
std::cerr << "Formato " << argv[0] << " <num_elem>" << std::endl;
return -1;
}
int n = atoi(argv[1]);
int range;
#if defined RADIXSORTLSD || defined RADIXSORTMSD
unsigned short * array = new unsigned short[n];
range = (n<65536)?n:65536;
#else
unsigned int * array = new unsigned int[n];
range = n;
#endif
srand(time(0));
for (int i = 0; i < n; i++){
array[i] = rand()%range;
}
#ifdef PRINT
PrintVector(array, n);
#endif
#include "inc/select.h" //Here is the problem for debugging
#ifdef PRINT
PrintVector(array, n);
#endif
}
includes.h
#include "../src/radixsortlsd.cpp"
#include "../src/radixsortmsd.cpp"
#include "../src/mergesort.cpp"
#include "../src/bitonicsort.cpp"
#include "../src/insertion.cpp"
#include "../src/slowsort.cpp"
#include "../src/selection.cpp"
select.h This is the code I want to debug. I decided to separate it from the main because it will grow a lot.
// The calls to CheckTime takes the first parameter as the direction to a function, previously defined inside the cpps of includes.h
#ifdef RADIXSORTLSD
CheckTime(&RadixSortLSD, array, n);
#endif
#ifdef RADIXSORTMSD
CheckTime(&RadixSortMSD, array, n);
#endif
#ifdef MERGESORT
CheckTime(&MergeSort, array, n);
#endif
#ifdef INSERTION
CheckTime(&Insertion, array, n);
#endif
#ifdef SLOWSORT
CheckTime(&SlowSort, array, n);
#endif
#ifdef SELECTION
CheckTime(&Selection, array, n);
#endif
#ifdef BITONICSORT
CheckTime(&BitonicSort, array, n);
#endif
I hope this help. Note that everything compiles great and works great (I made sure that the macros I defined when compiling are the correct ones)
Note: By debugging (not the right word) I meant checking how a function works (a function I don't fully understand).
Possibly you could break at MyFunction(), then run 'bt' command to see the stack. Then you see, is there any additional stack frame or what stack frames consist of in terms of source files, it might help
First of all:
A include is a preprocessor directive which never generates code. Debuggers can stop only on things which can be executed. Including a file works during compilation, not during runtime.
The next:
Your included files will define some values, functions, classes and a lot other. So you must give the debugger an idea where to stop.
And at all:
Including 'cpp' files is really trash! There are only very seldom reasons to do this.
But ok, how to proceed:
If your header file ( or included cpp file ) provides a function, you simply can do a break Func and run your program. No need to open any file in a gui for gdb before.
If you want to look inside the included files, you also can list myheader.h:1. The 1 one is the line of code you want to start looking into the file.
And a hint: Please provide much smaller code examples which persons can compile for themselves to give you more detailed help. You example is really bad to understand!
Example session:
Header: f.h
#include <stdlib.h>
void g(void)
{
malloc(4000);
}
void f(void)
{
malloc(2000);
}
main.cpp:
#include "f.h"
int main(void)
{
int i;
int* a[10];
for (i = 0; i < 10; i++) {
a[i] = (int*)malloc(1000);
}
f();
g();
for (i = 0; i < 10; i++) {
free(a[i]);
return 0;
}
}
Example session:
> gdb prog
gdb) break f
Breakpoint 1 at 0x40061a: file main.cpp, line 10.
(gdb) run
Starting program: /home/xxx/go
Breakpoint 1, f () at f.h:10
10 malloc(2000);
(gdb) list
5 malloc(4000);
6 }
7
gdb )
Now you can walk through your subroutine with step.
Related
I'm trying to implement a new datatype called HugeInteger in C++ with classes. I've encountered a problem that when I try to create new HugeInteger, my program terminates itself when the first number is printed. When I comment the statement the statement user enter a HugeInteger but the statement that displays the number is still there, the first number isn't written(the default value of the number is 0) and second number is filled by user. My try is as following:
HugeInteger.h
// HugeInteger class definition
#ifndef HUGEINT_H
#define HUGEINT_H
class HugeInteger
{
private:
int arr[40] = {0};
size_t len;
public:
void Input();
void Output();
};
#endif
HugeInteger.cpp
#include "HugeInteger.h"
#include <iostream>
#include <sstream> // to fill arr
void HugeInteger::Input()
{
std::string line;
int i;
std::getline(std::cin, line);
for (size_t i = 0; i < line.length(); i++)
{
arr[i] = line[i] - '0';
}
len = line.length();
}
void HugeInteger::Output()
{
int i = 0;
while (i < len)
std::cout << arr[i++];
}
main.cpp
#include <iostream>
#include "HugeInteger.h"
int main()
{
HugeInteger hui = HugeInteger();
//hui.Input(); // when this is commented, Output method does not work.
hui.Output();
HugeInteger hui2 = HugeInteger();
hui2.Input();
hui2.Output();
return 0;
}
Note: I've just perfomed another debug that I create another method called getLen so that I can access the len attribute. However, I put the code before and after Output method in the main.cpp, but I couldn't see the value of len neither these poisions. After that, I make the arr attribute as public, and tried to see the contents of it, and I couldn't see that either. I think my code doesn't work and I can somehow only see what I entered, after that the program is finished.
Note: I think I'm not facing a buffer overflow problem, because I always debugged my program with 3 4 digit numbers, so my array has contain 3-4 numbers and the rest is 0. Moreover, I'll probably put a code to handle this issue.
The call to Input() sets the value of the len member. Without the call, the member is uninitialized, but still used by Output().
Just initialize it to 0, similar to what you do with the array.
I am new to c++. Doing it for the past 9 months or so and didn't learn it by the books. I always learnt whatever I just tried to accomplish. This might have ended in me doing some sloppy codes, so I am happy if you guys would suggest advices for a more proper code, but mainly solve the issue at hand.
What my code does: It's supposed to create a structure that makes it easy for me find and use radii in two dimensions x[-50;50] y[-50;50] but only for integers. My declared structure for this task is indexed by "sqared radius" (max: 5000) and filled with:
an index (for later use of the array "radidx")
the amount of positions with the same radius
its true radius (sqrt)
the x and y position of each coordinate
Just so you know what's going on in my code.
Now the problem goes like this: If I declare the array "radidx" before the structure declaration I end up with my solution. But if I declare it after the structure, I get a segmentation error because entries in the structure seem to go terribly wrong.
As far as I know and a friend confirmed this. The order of declarations on top of my code - long before any of these declarations is used - shouldn't make a difference, so this must be because some sloppy coding of myself. I would like to improve on this in order to avoid similar issues in future codes and when putting this code here into use. Neither of us could figure out where and what went wrong.
#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <cmath>
#include <ctime>
#include <chrono>
#include <list>
#include <random>
using namespace std;
// int radidx[1030] = {0}; // Here it does work.
struct radii { int idx; int a=0; double r; int x[32]; int y[32]; };
radii radius[5000];
int radidx[1030] = {0}; // Here it doesn't work.
void rad_corr_init() {
int count [5001];
for (int i=0;i<5001;i++) count[i]=0;
/// Helper Function
/// count amount of positions with the same radius
for (int i=-50;i<51;i++)
for (int j=-50;j<51;j++)
count[i*i+j*j]++;
/// sort collected radii and exclude radii that don't exist so one can run a for-loop of an radius interval
int ik=0;
for (int i=1;i<5001;i++)
if(count[i]) {radidx[ik]=i; ik++;}
for (int i=-50;i<51;i++) // This is put here for testing
for (int j=-50;j<51;j++) { // This is put here for testing
int il = i*i+j*j; // This is put here for testing
radius[il].a=0; // This is put here for testing
} // This is put here for testing
/// Create Radius Structure
for (int i=-50;i<51;i++)
for (int j=-50;j<51;j++) {
int il = i*i+j*j;
int im = radius[il].a;
if (!radius[il].a) radius[il].r = sqrt(il);
radius[il].x[im] = i;
radius[il].y[im] = j;
radius[il].a++;
}
for (int i=0;i<1030;i++) {printf("%d\t%d\n",i,radidx[i]) /* This is put here for testing */ ;radius[radidx[i]].idx = i;}
}
int main() {
FILE * result = fopen( "result.txt", "w" );
rad_corr_init();
for (int i=0;i<1030;i++) {
int in = radidx[i];
int io = radius[in].a;
for (int j=0;j<io;j++) {
cout << i << '\t' << in << '\t' << radius[in].r << '\t' << j << '\t' << radius[in].x[j] << '\t' << radius[in].y[j] << endl;
fprintf(result, "%d\t%d\t%d\t%d\t%f\t%d\t%d\n", i, radius[in].idx, in, radius[in].r, j, radius[in].x[j], radius[in].y[j]);
}
}
// system("pause");
return 0;
}
I used the following commands for compiling (in case this is part of the issue):
g++ radius.cpp -std=c++11 -o ~[some name]/Desktop/run.out;time ~[some name]/Desktop/run.out
g++ -O4 radius.cpp -std=c++11 -o ~[some name]/Desktop/run.out;time ~[some name]/Desktop/run.out
Thank you guys for your help.
You have 5001 entries for count, but only 5000 for radius. When you access radius[50*50+50*50] (=radius[5000]) you exceed the bounds of the array and overwrite whatever is in memory after radius.
The solution is to change the declaration to radii radius[5001].
I am working on a C++ project for school in which the program will read in a list of numbers from a text file, store them in a dynamic array, then print them out to another text file. To be honest I'm a little lost with the pointers in this, and I am getting the error "A value of type "void" cannot be used to initialize an entity of type "int"" in my main source file.
Main.cpp (this is where I'm getting the error):
#include "dynamic.h"
int main
{
readDynamicData("input.txt","output.txt");
}
dynamic.cpp (the skeleton for the program):
#include "dynamic.h"
void readDynamicData(string input, string output)
{
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
int *temp = da.theArray;
da.theArray = new int[da.size];
ifstream in(input);
ofstream out(output);
in >> da.number; //prime read
while (!in.fail())
{
if (da.count < da.size)
{
da.theArray[da.count] = da.number;
da.count++;
in >> da.number; //reprime
}
else grow; //if there are more numbers than the array size, grow the array
}
out << "Size: " << da.size << endl;
out << "Count: " << da.count << endl;
out << "Data:" << endl;
for (int i = 0; i < da.size; i++)
out << da.theArray[i];
in.close();
out.close();
delete[] temp;
}
void grow(DynamicArray &da) //this portion was given to us
{
int *temp = da.theArray;
da.theArray = new int[da.size * 2];
for (int i = 0; i<da.size; i++)
da.theArray[i] = temp[i];
delete[] temp;
da.size = da.size * 2;
}
and dynamic.h, the header file:
#include <iostream>
#include <string>
#include <fstream>
#ifndef _DynamicArray_
#define _DynamicArray_
using namespace std;
void readDynamicData(string input, string output);
struct DynamicArray
{
int *theArray;
int count;
int size;
int number;
};
void grow(DynamicArray &da);
#endif
you have to add parenthesis to main or any function:
int main(){/*your code here ...*/};
2- you are using an unitialized objct:
DynamicArray da; //struct in the header file
da.count = 0;
da.size = 5; //initial array size of 5
so int* theArray is a member data and is uninitialized so welcome to a segfault
all the members of da are not initialized so you have to do before using it.
3- also you add parenthesis to grow function:
else grow(/*some parameter here*/); // grow is a function
4- using namespace std; in a header file is a very bad practice.
tip use it inside source
5- why making inclusion of iostream and string.. before the inclusion guard??
correct it to:
#ifndef _DynamicArray_
#define _DynamicArray_
#include <iostream>
#include <string>
#include <fstream>
/*your code here*/
#endif
main is a function so it needs brackets:
int main(){
// your code
return 0; // because it should return intiger
}
And. Your grow is also a function, so if you want to call it you write grow() and it needs DynamicArray as a parameter.
It is impossible to write working programs on C/C++ any programming language not knowing a basic syntax.
Global.h
#ifndef GLOBAL_H
# define GLOBAL_H
#define DEBUG
#ifdef DEBUG
# define IF_DEBUG( ... ) __VA_ARGS__
#else
# define IF_DEBUG( ... )
#endif /* DEBUG */
#endif /* GLOBAL_H */
Main.cpp
#include <string>
#include <iostream>
#include "Global.h"
int main() {
int A = 1;
int B = 2;
int C = 0;
IF_DEBUG(
std::cout << "\nStep 1> Calculating...\n";
)
C = A + B;
// DO WHATEVER
IF_DEBUG(
std::cout << "\nStep n> ...\n";
)
// ...
std::cout << C << std::endl;
// Note: I could also do some operations within the IF_DEBUG macro.
IF_DEBUG(
int X = 10;
int Y = 5;
int Z = X / Y;
std::cout << Z << std::endl;
)
IF_DEBUG(
std::cout << "\nDebugged! This program has been paused. Enter any key to continue!\n";
::getchar();
)
return 0;
}
Do you see how I defined IF_DEBUG in the Global header file (Global.h) and how I constantly used
it in the Main source file (Main.cpp) for debugging purposes?
Is it okay and safe to do that?
I am asking this question because I am unsure if its okay to do that. When I show this to my friend and he said its "bad" to do that. Therefore, I am unsure.
This is a very common and useful trick. But it's better not to have the #define DEBUG in the source code. You can define it in the compile command line instead. g++ -DDEBUG -c file.cpp will compile the code as if DEBUG was defined.
If you're using a Makefile you can add it to the CPPFLAGS (C Preprocessor Flags) variable: CPPFLAGS=-DDEBUG.
If you're using an IDE try to find the C Preprocessor Flags in the project settings.
I have simple class ina header file:
> cat Algorithms.hh
#ifndef Algorithms_hh
#define Algorithms_hh
#include<vector>
class Algorithms
{
public:
Algorithms();
void BubbleSort();
std::vector<int> myarray;
};
#endif
Then a corresponding c file:
> cat Algorithms.cc
#include <iostream>
#include <vector>
#include "Algorithms.hh"
Algorithms::Algorithms()
{
myarray.push_back(0);
}
void Algorithms::BubbleSort()
{
int i, j, flag = 1; // set flag to 1 to start first pass
int temp; // holding variable
int numLength = myarray.size();
for(i = 1; (i <= numLength) && flag; i++)
{
flag = 0;
for (j=0; j < (numLength -1); j++)
{
if (myarray[j+1] > myarray[j]) // ascending order simply changes to <
{
temp = myarray[j]; // swap elements
myarray[j] = myarray[j+1];
myarray[j+1] = temp;
flag = 1; // indicates that a swap occurred.
}
}
}
}
>
And then the main function:
> cat algo2.cc
#include <iostream>
#include <vector>
#include "Algorithms.hh"
using namespace std;
int main(int argc,char **argv)
{
Algorithms *arr=new Algorithms();
arr->myarray.push_back(1);
arr->myarray.push_back(2);
arr->myarray.push_back(100);
return 0;
}
>
When i compile the main:
I get the below error:
> CC algo2.cc
Undefined first referenced
symbol in file
Algorithms::Algorithms() algo2.o
ld: fatal: Symbol referencing errors. No output written to a.out
Can anyone tell me where i am wrong?
This is a linker error, the linker is telling you it can't find the definition of constructor of class Algorithms. You should compile with:
CC Algorithms.cc algo2.cc
You can identify it's a linker error because of the ld: in front of the error.
And of course as stated by Kerrek SB you need to declare your constructor without the Algorithms:: in front of it...
You've just forgotten to include both .cc files into compiling:
cc algo2.cc Algorithms.cc
If you include header file with declarations, like
#include "Algorithms.hh"
you should also provide implementation, definition in .c, or .lib. or load library with definition dynamically. In your case your library is Algorithms.cc, so just add it into compilation stage, and then both temporary object files
Algo2.a + Algorithms.a
will go to
a.out