First of all I am not proficient programing, so please be lenient. :)
I was curious what causes the error called "Stack overflow". I am using Visual C++ 2010 Express.
struct elem
{
BITMAP * colltile;
elem * next;
};
/* put some code here */
int collision_map (unsigned int poz_x, unsigned int poz_y)
{
elem * wsk = this->where_the_head_of_list_is;
int x,y;
x = poz_x%64; //coord x on tile (0-63px)
y = poz_y%64; //coord y on tile (0-63px)
poz_x /= 64; //preparing poz_x and poz_y to point on a tile on a grid
poz_y /= 64; //integers do not have to be floored
//for (int j=(poz_y*(this->size_x)+poz_x); j>0; j--) //normally works... but
for (int j=0; j<1000; j++) //this version is not
{
if ((!(wsk = wsk->next)) ||
((poz_x+1) > this->size_x) ||
((poz_y+1) > this->size_y))
{ //should check if there is no new pointer or just out of map
return -1;
}
}
return getpixel(wsk->colltile, x, y);
}
Why is the condition not working when j reaches the value of length of the list?
Things you can/have to do:
Adding debug output will help you find the error. Add some std::cerr << wsk << std::endl in your code and check if/when it becomes zero.
Possibly the pointer is zero at the beginning of your function at elem* wsk= .... If this is the case wsk->next will access a null pointer. You have to check if the pointer is valid.
Since you have pointer members in your class (as indicated by this->where_the_head_of_list_is) you need to implement copy constructor, assignment operator and destructor, which you might not have done. See here for an explanation.
Related
I have an array called int **grid that is set up in Amazon::initGrid() and is made to be a [16][16] grid with new. I set every array value to 0 and then set [2][2] to 32. Now when I leave initGrid() and come back in getGrid() it has lost its value and is now 0x0000.
I don't know what to try, the solution seems to be really simple, but I'm just not getting it. Somehow the data isn't being kept in g_amazon but I could post the code.
// Returns a pointer to grid
int** Amazon::getGridVal()
{
char buf[100];
sprintf_s(buf, "Hello %d\n", grid[2][2]);
return grid;
}
int Amazon::initGrid()
{
int** grid = 0;
grid = new int* [16];
for (int i = 0; i < 16; i++)
{
grid[i] = new int[16];
for (int j = 0; j < 16; j++)
{
grid[i][j] = 0;
}
}
grid[2][2] = 32;
return 0;
}
int **grid;
g_amazon = Amazon::getInstance();
g_amazon->initGrid();
grid = g_amazon->getGridVal();
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int index;
index = (width * 4 * i) + (4 * j);
int gridval;
gridval = grid[i][j];
lpBits[index] = gridval;
lpBits[index + 1] = gridval;
lpBits[index + 2] = gridval;
}
}
It crashes when I run it at the line where sprintf_s prints out [2][2] and it also crashes when I get to gridval = grid[i][j] because it's at memory location 0x000000.
The variable
int** grid
in the initGrid() function is a local variable. Edit** When the function returns the variable is popped off the stack. However, since it was declared with the new operator the memory still exists on the heap; it is simply just not pointed to by your global grid variable.
#Dean said in comment:
I have grid as an int** grid; in class Amazon {}; so shouldn't it stay in memory or do I need a static var.
That is the problem:
local int **grid; on Amazon::initGrid::
is masking
member int **grid; on Amazon::
as the first context has higher priority in name lookup.
So initGrid() allocates memory referenced only by a local pointer. That pointer no longer exists when you return from this function, Amazon::grid was never touched on initialization and you're also left with some bad memory issues.
So, as commented by #Remy-Lebeau, I also suggest
Consider using std::vector> or std::array, 16> instead. There is no good reason to use new[] manually in this situation.
I've tried the (somewhat questionable) convention of deleteing after usage, but that doesn't seem to work. The program is supposed to receive an input of a single integer, sort a randomly created array, and print elapsed time for sorting, yet when I leave the delete in there, the program abnormally ends without even a warning after I do the input. In other words, it crashes. However, when I comment out just the delete line, the program executes perfectly.
The MWE is measuring time for a simple Quick Sort Algorithm, and since this is a school project I cannot change the main() function and using the QuickSort class and its pointers, etc..
The only things I can change are the stuff that goes in the various functions, and although it does seem that set(double*, int) can just be integrated into the constructor, that's not a possible option here for some reason.
The objective is to define a default double* in the constructor, and then delete it and copy input_array into this->arr in set:
EDIT: I use Windows 10 and the GCC C++ Compiler from MinGw-w64. All compilations have been executed in the Windows Command Prompt.
main.cpp
#include <iostream>
#include <cstdlib> // Just for good measure, though this shouldn't be needed
#include "Sort.hpp"
bool check_quick(QuickSort *quick_sort) {
int i = 0;
while(i < (quick_sort->size) - 1) {
if (quick_sort->arr[i] > quick_sort->arr[i + 1]) break;
++i;
} if (i == (quick_sort->size) - 1) return true;
else return false;
}
int main() {
int n; cin >> n;
double *input_array = new double[n];
srand((unsigned int)time(NULL));
for (int k = 0; k < n; k++) input_array[k] = (double)((rand() % n));
QuickSort* quick_sort = new QuickSort();
quick_sort->set(input_array, n);
quick_sort->run();
if (check_quick(quick_sort)) {
cout << "QuickSort is validated" << endl << endl;
} delete quick_sort;
}
Sort.hpp
#define CLOCKS_PER_SECOND 1000
#include <iostream>
#include <ctime>
#include <iomanip> // Use to call setprecision(4)
using namespace std;
class QuickSort {
friend bool check_quick(QuickSort*); // Give access for private variables
public:
void print_time() const {
cout << "QuickSort : " << fixed << setprecision(4) << seconds
<< " sec" << endl;
// << fixed << setprecision(4) always prints to four numbers after point
}
QuickSort() {
this->arr = new double[10];
for (int i = 0; i < 10; ++i) this->arr[i - 1] = i; // Set default array
seconds = clock(); // Set current Millisecond to starting time
}
~QuickSort() {
delete this->arr; // Delete array in object of this class
}
void sorter(double *arr, int begin, int end) { // Sorting Recursive Function
// Size of array without pivot is: end - begin
int pivot = arr[end];
// PIVOT is element at end of subarray "arr[begin...end]"
int i = begin, j = end;
while (i <= j) {
while (arr[i] < pivot) i++; // Increment until arr[i] is larger than
while (arr[j] > pivot) j--; // Decrement until arr[j] is lesser than
if (i <= j) { // If the larger element precedes lesser element
swap(arr[i], arr[j]); // Call Swap function
i++; j--;
} // If i is larger than j now, i was 1 lesser than j before,
// effectively leaving no more elements to scan.
}
if (begin < j) sorter(this->arr, begin, j); // Recursive, larger part
if (end > i) sorter (this->arr, i, end); // Recursive, lesser part
}
void run() {
sorter(this->arr, 0, this->size - 1); // Call Sorter function
seconds = (double)(clock() - seconds) / (double)(CLOCKS_PER_SECOND);
// Calculate Difference of Ticks and divide by Ticks per second.
// Now, `seconds` is passed seconds with millisecond precision.
}
void set(double *arr, int size) {
this->arr = new double[size]; // Make new array of `size` size
for (int i = 0; i < size; i++) this->arr[i] = arr[i]; // Copy input_arr
for (int i = 0; i < size; i++) cout << this->arr[i] << endl; // Copy input_arr
this->size = size; // Save global `size` to object of class
}
void swap(double &p, double &q) { // Swap Function
// Ampersand precedence to change input
double x = p; // Temporary `double` saver
p = q; // p is q
q = x; // q is x, which is p
}
private:
double *arr;
int size;
double seconds;
};
In your QuickSort constructor you are writing outside the bounds of the array that you are allocating:
this->arr = new double[10];
for (int i = 0; i < 10; ++i) this->arr[i - 1] = i; // Set default array
In the first iteration i is 0 so this->arr[i - 1] writes to the element -1. This is only crashing when you call delete as if you don't the runtime doesn't notice this corruption and exits cleanly.
Presumably just changing i-1 to i will produce the desired behaviour.
The first line of QuickSort::set:
this->arr = new double[size]; // Make new array of `size` size
leaks the array allocated in QuickSort's constructor. You need to delete[] that array first, before assigning arr to point to another one:
delete[] arr;
this->arr = new double[size]; // Make new array of `size` size
If this were the real world, and not a shcool assignment, it would be much better not to use a raw pointer in this case. Rather, a std::vector<double> would be much more appropriate.
A quick look reveals that you are using delete instead of delete[]..
this line:
delete this->arr; // Delete array in object of this class
should be:
delete[] this->arr; // Delete array in object of this class
Additionally, as per the convention of delete you should also do this:
delete[] this->arr;
this->arr = nullptr; // This is important, else your are double deleting which is calling for trouble.
I am a beginning programmer writing a graphical game using SDL. The function that splits a tile-sheet into sections or "clips" and puts it into a array and the function that draws specific "clips" onto the screen are not working as intended.
void split_tilesheet(int width, int height, int space, Entity * ent){
std::cout << "Splitting Tileset...";
int t_width = (width / SPR_W);
int t_height = (height / SPR_H);
int numTiles = (t_width * t_height);
ent = new Entity [numTiles + 1];
if( ent == NULL){
err("!failed to alloc!");
}else{
std::cout << "allocated"<< std::endl;
}
int count = 0;
for(int i = 0; i < t_width; i++){
for(int j = 0; j < t_height; j++){
ent[count].bounds.x = i * SPR_W;
ent[count].bounds.y = j * SPR_H;
ent[count].bounds.w = SPR_W;
ent[count].bounds.h = SPR_H;
ent[count].id = ent[i].x + ( ent[i].y * t_width);
count++;
}
}
}
void draw_room(char tiledata[MAP_MAX_X][MAP_MAX_Y], Entity * ent){
SDL_Rect bounds;
for(int x = 0; x < MAP_MAX_X; x++){
for(int y = 0; y < MAP_MAX_Y; y++){
if(tiledata[x][y] == '0' || tiledata[x][y] == ' ' || tiledata[x][y] == '\n' ){
draw_img(x * SPR_W , y * SPR_H, tiles, bounds, ent[0].bounds);
}
if(tiledata[x][y] == '1'){
draw_img(x * SPR_W , y * SPR_H, tiles, bounds, ent[1].bounds);
}
}
}
}
class Entity
{
public:
SDL_Rect bounds;
SDL_Surface* sprite;
int id;
int x;
int y;
int w, h;
};
I was trying to use pointers to dynamically allocate the memory at runtime.
The program compiles, but segfaults. gdb says that the segfault is due to the draw_room() function, but I cannot figure out why. The pointer I was passing to the draw_room function was:
Entity * floor0_clips = NULL;
This didn't work either
Entity * floor0_clips;
Please help...
C++ uses pass-by-value (unless you specify pass-by-reference), which you didn't.
A variable in a function is a copy of the argument given. For example:
int func(int x)
{
x = 5;
}
int main()
{
int y = 6;
func(y);
// here, `y` is still `6`
}
Your case is fundamentally the same as this. You send floor0_clips to a function, the function updates a copy of it, leaving the original unchanged.
To use pass-by-reference instead, put the & symbol just before the variable name in the function's parameter list, i.e. in your case Entity * &ent . Do not change anything in the code which calls the function; it is the function's parameter list declaration that decides whether the value is passed by value or by reference.
NB. You appear to be allocating too many Entities anyway (why the + 1?).
I'm having trouble understanding what the difference between these two code snippets is:
// out is of type char* of size N*D
// N, D are of type int
for (int i=0; i!=N; i++){
if (i % 1000 == 0){
std::cout << "i=" << i << std::endl;
}
for (int j=0; j!=D; j++) {
out[i*D + j] = 5;
}
}
This code runs fine, even for very big data sets (N=100000, D=30000). From what I understand about pointer arithmetic, this should give the same result:
for (int i=0; i!=N; i++){
if (i % 1000 == 0){
std::cout << "i=" << i << std::endl;
}
char* out2 = &out[i*D];
for (int j=0; j!=D; j++) {
out2[j] = 5;
}
}
However, the latter does not work (it freezes at index 143886 - I think it segfaults, but I'm not 100% sure as I'm not used to developing on windows) for a very big data set and I'm afraid I'm missing something obvious about how pointer arithmetic works. Could it be related to advancing char*?
EDIT: We have now established that the problem was an overflow of the index (i.e. (i*D + j) >= 2^32), so using uint64_t instead of int32_t fixed the problem. What's still unclear to me is why the first above case would run through, while the other one segfaults.
N * D is 3e9; that doesn't fit in a 32 bit int.
When using N as size of array, why use int?
does a negative value of an array has any logical meaning?
what do you mean "doesn't work"?
just think of pointers as addresses in memory and not as 'objects'.
char*
void*
int*
are all pointers to memory addresses, and so are exactly the same, when are defined or passes into a function.
char * a;
int* b = (char*)a;
void* c = (void*)b;
a == b == c;
The difference is that when accessing a, a[i], the value that is retrieved is the next sizeof(*a) bytes from the address a.
And when using ++ to advance a pointer the address that the pointer is set to is advanced by
sizeof(pointer_type) bytes.
Example:
char* a = 1;
a++;
a is now 2.
((int*)a)++;
a is now 6.
Another thing:
char* a = 10;
char* b = a + 10;
&(a[10]) == b
because in the end
a[10] == *((char*)(a + 10))
so there should not be a problem with array sizes in your example, because the two examples are the same.
EDIT
Now note that there is not a negative memory address so accessing an array with a signed negative value will convert the value to positive.
int a = -5;
char* data;
data[a] == data[MAX_INT - 5]
For that reason it might be that (when using sign values as array sizes!) your two examples will actually not get the same result.
Version 1
for (int i=0; i!=N; i++) // i starts at 0 and increments until N. Note: If you ever skip N, it will loop forever. You should do < N or <= N instead
{
if (i % 1000 == 0) // if i is a multiple of 1000
{
std::cout << "i=" << i << std::endl; // print i
}
for (int j=0; j!=D; j++) // same as with i, only j is going to D (same problem, should be < or <=)
{
out[i*D + j] = 5; // this is a way of faking a 2D array by making a large 1D array and doing the math yourself to offset the placement
}
}
Version 2
for (int i=0; i!=N; i++) // same as before
{
if (i % 1000 == 0) // same as before
{
std::cout << "i=" << i << std::endl; // same as before
}
char* out2 = &out[i*D]; // store the location of out[i*D]
for (int j=0; j!=D; j++)
{
out2[j] = 5; // set out[i*D+j] = 5;
}
}
They are doing the same thing, but if out is not large enough, they will both behave in an undefined manner (and likely crash).
What is the problem here in this code?
It gives segmentation fault. I found value of size in vector (int *a)
is no more 3. How is this?
#include <iostream>
using namespace std;
class vector
{
int *v;
int size;
public:
vector(int m)
{
v = new int[size = m];
for(int i=0; i<size; i++)
v[i] = 0;
}
vector (int *a)
{
for(int i=0; i<size; i++)
v[i] = a[i];
}
int operator*(vector &y)
{
int sum = 0;
for(int i=0; i<size; i++)
sum += this -> v[i] * y . v[i];
return sum;
}
};
int main()
{
int x[3] = {1,2,3};
int y[3] = {4,5,6};
vector v1(3);
vector v2(3);
v1 = x;
v2 = y;
int R = v1 * v2;
cout << "R = " << R;
return 0;
}
Sincerely,
Srinivas Nayak
Apart for the problem with the allocation in your constructor vector (int *a), you also need an overloaded assignment operator:
int operator=(int *a) {
for(int i=0; i<size; i++)
v[i] = a[i];
}
Since the following two make use of it:
v1 = x;
v2 = y;
This is not surprising at all.
Your first constructor seems ok, the second one does miss the allocation for v.
Edit: v1 = x and v2 = y doesn't make sense without overloading operator=.
In essence the reason it generates a fault is in the line
v1=x;
As you have no assignment operator this in effect becomes:
v1=vector(x)
Which called your int * constructor. This constructor runs with size initialised to garbage which causes the seg fault as the loop progresses towards invalid memory.
Strategically the problem is you want create a new object for a int * but you don't know how big the array is that you are pointing at.
Your code looks like you want to assume that the array is the correct size for the currently defined vector in which case the operator you want to define this function in preference to the constructor: operator=(int *)
You generally seem a bit confused about which object is which for example
sum += this -> v[i] * y . v[i];
would normally jusy be written as in this context
sum += v[i] * y . v[i];
I hope this is homework!
Otherwise you should be using std::Vector
Couple of problems:
A constructor should initialize all members.
Neither constructor does this.
The copy constructor (or what seems to be) is not defined incorrectly.
Because your class manages a RAW pointer you need to see "The rule of three"
ie you are missing the assignment operator
Prefer to use initializer lists when you can
In addition to all the correct answers here, consider adding keyword explicit before all your constructors that accept only one argument. That way it will never be confused with assignment operations. Here's another question that explains it.
vector (int *a)
{
for(int i=0; i<size; i++)
v[i] = a[i];
}
This constructor couldn't possibly work.
The v member is not initialized. You have not allocated storage for the values.
The size member is uninitialized. The loop will try to read an undeterminate amount of values from the passed pointer.
There is no way to initialize size. If you are given just an int*, there is no way to determine how large the pointed array is (if the pointer even points into an array in the first place). This is the reason, why the number of elements in the array has to be passed separately (and why plain arrays are a PITA).