ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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;
}
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.
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.
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
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
rude cheap shots.
I see how it came off that way. But that wasn't my intent.
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.
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).
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);
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).
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;
}
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.