LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-01-2015, 03:46 PM   #1
mreff555
Member
 
Registered: Sep 2011
Location: Philly
Distribution: Gentoo
Posts: 473

Rep: Reputation: Disabled
c++ dynamic memory


I'm trying to write a simple program to resize a matrix and I keep getting segmentation faults. Can anybody give me an idea what I am doing wrong?

Code:
#define maxX 10
#define maxY 10
#include <iostream>
#include <cassert>
using namespace std;

int** createMatrix( int x, int y ){
	assert( x > 0 );
	assert( y > 0 );
	int ** M = new int*[y];
	for( int i =0; i < y; i++ )
		M[i] = new int[x];
	return M;
	}
int** resizeMatrix( int** old, int x, int y ){
	assert( x > 0 );
	assert( y > 0 );
	int ** M = new int*[y];
	for( int i =0; i < y; i++ )
		M[i] = new int[x];
	for( int i =0; i < 10; i++)
		for( int j=0; j< 10; j++)
			M[x][y] = old[i][j];
	return M;
	
	}

int main(){
	int **grid = createMatrix( 10,10 );
	grid[1][2] = 5;
	cout <<grid[1][2]<<endl;
	grid = resizeMatrix( grid, 20,20);
	cout <<grid[1][2]<<endl;
	}
 
Old 04-01-2015, 04:42 PM   #2
millgates
Member
 
Registered: Feb 2009
Location: 192.168.x.x
Distribution: Slackware
Posts: 852

Rep: Reputation: 389Reputation: 389Reputation: 389Reputation: 389
Hi,
have you considered using a debugging tool such as gdb or valgrind?
 
1 members found this post helpful.
Old 04-01-2015, 06:16 PM   #3
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
I read as far as the first obvious seg fault in your code:
Code:
 M[x][y] = old[i][j];
x and y are the limits of M[][] not valid indexes.

Maybe you intended:

Code:
 M[i][i] = old[i][j];
The hard coded 10's in the resizeMatrix function are so lame, it is hard to look past those and guess where you think you are going. But wherever that is needs that [x][y] fixed first.

Last edited by johnsfine; 04-01-2015 at 06:18 PM.
 
Old 04-01-2015, 09:28 PM   #4
mreff555
Member
 
Registered: Sep 2011
Location: Philly
Distribution: Gentoo
Posts: 473

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by johnsfine View Post
I read as far as the first obvious seg fault in your code:
[code]
The hard coded 10's in the resizeMatrix function are so lame, it is hard to look past those and guess where you think you are going. But wherever that is needs that [x][y] fixed first.
The variables were changed in an effort to troubleshoot. Thanks for the advice, and rude cheap shots.
 
Old 04-02-2015, 01:11 AM   #5
a4z
Senior Member
 
Registered: Feb 2009
Posts: 1,727

Rep: Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742
if you need dynamic size, use std::vector
if you know the size at compile time, use std::array

dummy code
Code:
using MatrixType = std::vector<int> ;
using Matrix = std::vector<MatrixType>

Matrix m;
m.resize(10)
for( auto& r : m) r.resize(10)
if the Matrix grows, you might want to give the elements default values, then you need something other in the loop
 
1 members found this post helpful.
Old 04-02-2015, 07:06 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by johnsfine View Post
I read as far as the first obvious seg fault in your code:
I only meant I hadn't looked at main, so I hadn't thought about the whole execution sequence, so if your code had more than one seg fault in it, I hadn't necessarily solved the right bug for your immediate progress.

Quote:
Originally Posted by johnsfine View Post
it is hard to look past those and guess where you think you are going.
That really does mean only what it says. Your intent (and debugging status) may be clear to you, but not to me. So I can know things like that [x][y] being wrong, but only guess that you wanted [i][j] instead (as oppose to missing a bunch of other code that could have made the [x][y] correct).

When the code shows the intention more clearly, it is easier to be sure about the appropriate correction to a bug.

Quote:
Originally Posted by mreff555 View Post
rude cheap shots.
I see how it came off that way. But that wasn't my intent.
 
Old 04-02-2015, 07:54 AM   #7
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,672
Blog Entries: 4

Rep: Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945
Quote:
Originally Posted by a4z View Post
if you need dynamic size, use std::vector
if you know the size at compile time, use std::array
That's a key point when working with C++. There's a very rich standard-library available to do almost anything, and much more sophisticated memory-management than "vanilla C" ever could offer. Get to know the libraries very, very well.
 
Old 04-02-2015, 08:18 AM   #8
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by sundialsvcs View Post
That's a key point when working with C++. There's a very rich standard-library available to do almost anything, and much more sophisticated memory-management than "vanilla C" ever could offer.
If you do serious enough work in C++, you will run into situations in which you need "containers" that the standard library can't provide.

I hope the code that was posted was part of a learning exercise and not production code. Assuming it was done for learning, I see nothing wrong with learning how to roll your own container despite std being better. I don't even see anything wrong with learning to roll your own before learning how to use the std version. That will help you really understand what your programs are doing later.

If you never learn to roll your own container for situations where use of std is better, you won't begin to have a clue about situations where std is worse.

Quote:
Get to know the libraries very, very well.
Maybe that works for some people. Certainly not for me. I am strong with concepts and not with memorized detail. In the Internet world, there is very little anyone like me should get to "know well". It is much better to understand the concepts well and know where the online site with the details is (or even just how to find that again with google).

Last edited by johnsfine; 04-02-2015 at 08:22 AM.
 
1 members found this post helpful.
Old 04-02-2015, 11:22 AM   #9
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,871
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
@OP: Start here:
Code:
typedef struct IntMatrix {
    int n; // rows
    int m; // columns
    int **data;
} IntMatrix;

#define EmptyIntMatrix {0,0,NULL}

int IM_Alloc (IntMatrix *into, int n, int m);
int IM_Free (IntMatrix *pmat);
int *IM_Access (IntMatrix *pmat, int i, int j);
 
Old 04-02-2015, 11:37 AM   #10
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by NevemTeve View Post
@OP: Start here:
Possibly the advice you're trying to give is to be organized about keeping track of the current sizes of the matrix, which typically means keeping the sizes and pointer together in a struct.

But that is better said by communicating the concept than by going into detail that imply your renaming of functions is part of the suggestion, or the switch from the OP's C style algorithm in C++ syntax to your more C specific syntax.

If you did mean to convey anything other than keeping the size with the pointer, I disagree with your suggestions (your #define is especially ugly given the OP showed C++ syntax and doesn't need the terrible uses of #define that are often needed in serious C programming).
 
Old 04-02-2015, 11:47 AM   #11
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
Although it is C++ the OP will need to track his sizes and would be better off with malloc and realloc then new and an iterative copy. It's a good exercise for sure.

Here's a skeleton version:
Code:
#include <iostream>
#include <cstdlib>

template <class T>
class Matrix {
private:
        size_t m_current_rows;
        size_t m_current_cols;
        T** m_buffer;
public:
        Matrix (size_t rows, size_t cols) : m_current_rows (rows), m_current_cols (cols) {
                m_buffer = (T**) malloc (sizeof m_buffer[0] * m_current_rows);
                for (int i = 0; i < m_current_rows; ++i) {
                        m_buffer[i] = (T*) malloc (sizeof m_buffer[0][0] * m_current_cols);
                }
        }

        ~Matrix () {
                for (int i = 0; i < m_current_rows; ++i) {
                        free (m_buffer[i]);
                }
                free (m_buffer);
        }

        void put (T item, size_t row, size_t col) {
                if (m_buffer == nullptr) throw 1;

                if (row >= m_current_rows || col >= m_current_cols) {
                        m_current_rows *= 2;
                        m_current_cols *= 2;

                        T** tmp = (T**) realloc (m_buffer, sizeof m_buffer[0] * m_current_rows);
                        if (tmp != nullptr) {
                                m_buffer = tmp;

                                for (int i = 0; i < m_current_rows; ++i) {
                                        T* tmp = (T*) realloc (m_buffer[i], sizeof m_buffer[0][0] * m_current_cols);
                                        if (tmp != nullptr) {
                                                m_buffer[i] = tmp;
                                        } else {
                                                throw 1;
                                        }
                                }

                        } else {
                                throw 1;
                        }


                }

                m_buffer [row][col] = item;
        }

        T& get (size_t row, size_t col) {
                if (row > m_current_rows || col > m_current_cols) {
                        throw 1;
                }

                return m_buffer[row][col];
        }
};

int main () {
        Matrix<int> m (2, 2);

        try {
                for (int i = 0; i < 10; ++i) {
                        for (int j = 0; j < 10; ++j) {
                                m.put (i+j, i, j);
                        }
                }

                for (int i = 0; i < 10; ++i) {
                        for (int j = 0; j < 10; ++j) {
                                std::cout << m.get (i, j) << std::endl;
                        }
                }
        } catch (int i) {
                std::cerr << "exception thrown\n";
        }

        return 0;
}
 
1 members found this post helpful.
Old 04-04-2015, 11:42 AM   #12
a4z
Senior Member
 
Registered: Feb 2009
Posts: 1,727

Rep: Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742Reputation: 742
Quote:
Originally Posted by johnsfine View Post
If you do serious enough work in C++, you will run into situations in which you need "containers" that the standard library can't provide.
this happens sometimes, and if you do not find the container you need in the boost libraries than you use something like eigen or Armadillo or something similar that fits you need.

but I totally agree that is is a useful exercise to implement some containers self to see and understand how they work
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] how to allocate dynamic memory to shared memory golden_boy615 Programming 7 04-25-2018 02:34 PM
C, dynamic memory trouble isamuede Programming 11 04-02-2012 11:00 PM
Dynamic shared memory user777 Linux - General 6 02-16-2009 07:36 AM
[C++] Classes and dynamic memory Ephracis Programming 17 12-30-2006 01:55 AM
Dynamic Memory Allocation jvff Programming 1 09-05-2005 05:01 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration