Thread: Won't get out of the function!

  1. #1
    Registered User
    Join Date
    Dec 2005
    Posts
    13

    Unhappy Won't get out of the function!

    Hello!

    The following code, surprisingly, works very well until it is time to return to the main function. I really never saw such an error... I'm working with MS Visual Studio 2005 Pro and I've tried restarting the whole application, running it in debug and release mode.. Nothing fixes it.

    I'd really appreciate if someone would find the reason why it won't get out of the function.

    Oh, I copied/pasted the for loop that prints the table in the function, just to see if the reste of the code seems to work, and yes, it prints the table read from the file very well. I'll include the test file after the code...

    Thank you very much,

    Maxime

    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Prototypes
    void loadImage(short **table, short **secTable, unsigned short &rows, unsigned short &cols);
    
    int main() {
    	short** image = new short*[1];    // tables
    	short** zones = new short*[1];
    	unsigned short rows, cols;      // dimensions
    	loadImage(image, zones, rows, cols);
    	cout << "de retour dans le programme\n";
    
    	cout << "rows: " << rows << endl << "cols: " << cols << endl;
    	for (int i = 0;i < rows;i++){
    		for (int j = 0;j < cols;j++) {
    			cout << image[i][j] << " ";
    		}
    		cout << endl;
    	}
    
    	delete []image[0];
    	delete []image;
    	delete []zones[0];
    	delete []zones;
    	return 0;
    }
    
    // Reads the picture and stores information in variables
    void loadImage(short **table, short **secTable, unsigned short &rows, unsigned short &cols) {
    	ifstream picture("lac.txt");
    	if (!picture) {
    		cout << "Erreur lors de l'ouverture du fichier lac.txt\n";
    		exit(1);
    	}
    	picture >> rows; // dimensions
    	picture >> cols;
    	//table = new short*[rows];   // allocate tables
    	table[0] = new short[cols * rows];
    	for (int i = 1;i < rows;i++)
    		table[i] = table[i-1] + cols;
    	//secTable = new short*[rows];
    	secTable[0] = new short[cols * rows];
    	for (int i = 1;i < rows;i++)
    		secTable[i] = secTable[i-1] + cols;
    	for (int r = 0;r < rows;r++) {   // read picture
    		for (int c = 0;c < cols;c++) {
    			picture >> table[r][c];
    		}
    	}
    	picture.close();
    	for (int i = 0;i < rows;i++){
    		for (int j = 0;j < cols;j++) {
    			cout << table[i][j] << " ";
    		}
    		cout << endl;
    	}
    	cout << "end of the function\n";
    	return;
    	cout << "this should NEVER run\n";
    }

    Test file (lac.txt):
    Code:
    10 10
    1 1 1 0 0 0 0 2 0 0
    1 0 0 0 0 0 1 0 1 0
    1 0 0 0 0 0 0 1 0 0
    0 0 0 0 0 1 0 0 1 0
    0 0 0 1 0 0 2 0 1 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 0 2 1 1 0 0 0
    0 0 0 0 1 0 0 0 0 0
    1 0 0 0 0 0 0 1 1 1

    And let me add the actual output of the program:
    Code:
    1 1 1 0 0 0 0 2 0 0
    1 0 0 0 0 0 1 0 1 0
    1 0 0 0 0 0 0 1 0 0
    0 0 0 0 0 1 0 0 1 0
    0 0 0 1 0 0 2 0 1 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 0 2 1 1 0 0 0
    0 0 0 0 1 0 0 0 0 0
    1 0 0 0 0 0 0 1 1 1
    end of the function

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You're either lucky or unlucky -- I get "Segmentation fault", which is what I would expect given the complete unsuitability of
    Code:
    table[0] = new short[cols * rows];
    in making a 2-D array. Why not do table = new short[rows][cols], other than that's a real array and not an short **? If you do want the short ** approach, you're going to have to use a for-loop. (First by setting table = new short*[rows], and then by setting each table[i] = new short[cols].)
    Last edited by tabstop; 11-01-2008 at 03:19 PM. Reason: int -> short

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Why use this complex code at all when there is std::vector?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    Dec 2005
    Posts
    13
    Quote Originally Posted by tabstop View Post
    You're either lucky or unlucky -- I get "Segmentation fault", which is what I would expect given the complete unsuitability of
    Code:
    table[0] = new short[cols * rows];
    in making a 2-D array. Why not do table = new short[rows][cols], other than that's a real array and not an short **? If you do want the short ** approach, you're going to have to use a for-loop. (First by setting table = new short*[rows], and then by setting each table[i] = new short[cols].)
    I wanted to do the table = new short[rows][cols] thing first, but that was even less working. (I have to say I'm new to pointers and dynamical allocation of memory.) Here I try something else, based on a few examples form the book I'm learning from (there's nothing really specific in it about what bugs me here):

    Code:
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    // Prototypes
    void loadImage(short *table, short *secTable, unsigned short &rows, unsigned short &cols);
    
    int main() {
    	short* image;    // tables
    	short* zones;
    //	short** image = new short*[1];    // tables
    //	short** zones = new short*[1];
    	unsigned short rows, cols;      // dimensions
    	loadImage(image, zones, rows, cols);
    	cout << "de retour dans le programme\n";
    
    	cout << "rows: " << rows << endl << "cols: " << cols << endl;
    	for (int i = 0;i < rows;i++){
    		for (int j = 0;j < cols;j++) {
    			cout << image[i][j] << " ";
    		}
    		cout << endl;
    	}
    
    /*	delete []image[0];
    	delete []image;
    	delete []zones[0];
    	delete []zones;
    */	return 0;
    }
    
    // Reads the picture and stores information in variables
    void loadImage(short *table, short *secTable, unsigned short &rows, unsigned short &cols) {
    	ifstream picture("lac.txt");
    	if (!picture) {
    		cout << "Erreur lors de l'ouverture du fichier lac.txt\n";
    		exit(1);
    	}
    	picture >> rows; // dimensions
    	picture >> cols;  
    	table = new short[rows][cols];
    	secTable = new short[rows][cols];
    /*	table[0] = new short[cols * rows];  // allocate tables
    	for (int i = 1;i < rows;i++)
    		table[i] = table[i-1] + cols;
    	secTable[0] = new short[cols * rows];
    	for (int i = 1;i < rows;i++)
    		secTable[i] = secTable[i-1] + cols;
    */	for (int r = 0;r < rows;r++) {   // read picture
    		for (int c = 0;c < cols;c++) {
    			picture >> table[r][c];
    		}
    	}
    	picture.close();
    	for (int i = 0;i < rows;i++){
    		for (int j = 0;j < cols;j++) {
    			cout << table[i][j] << " ";
    		}
    		cout << endl;
    	}
    	cout << "end of the function\n";
    	return;
    	cout << "this should NEVER run\n";
    }
    But then I get these errors preventing me from compiling:
    Code:
    1>cyanobac.cpp
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(33) : error C2109: subscript requires array or pointer type
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(54) : error C2540: non-constant expression as array bound
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(54) : error C2440: '=' : cannot convert from 'short (*)[1]' to 'short *'
    1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(55) : error C2540: non-constant expression as array bound
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(55) : error C2440: '=' : cannot convert from 'short (*)[1]' to 'short *'
    1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(64) : error C2109: subscript requires array or pointer type
    1>c:\documents and settings\administrator\my documents\udes\s1\app 6\cyanobac\cyanobac\cyanobac.cpp(70) : error C2109: subscript requires array or pointer type
    1>cyanobac - 7 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    :S

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Dude, we are telling you that you do need this complexity. Use std::vector instead for complexity likely this. If you wish to learn dynamic memory, pick something simpler.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    When I counted to line 33, I got
    Code:
    // Reads the picture and stores information in variables
    so your error messages don't match the code you posted.

    You've got choices: you can allocate [rows*cols], but you're not allowed to use double-subscripted notation (you'll have to do the math yourself). You can allocate [rows][cols], but the result is not a short *, nor is it a short **, but a short *[cols]. Or you can use a vector< vector<short> >.

  7. #7
    Registered User
    Join Date
    Dec 2005
    Posts
    13
    Oh sorry for the line number, I didn't copy the header ... :S The code actually started at line 13.


    Quote Originally Posted by Elysia View Post
    Dude, we are telling you that you do need this complexity. Use std::vector instead for complexity likely this. If you wish to learn dynamic memory, pick something simpler.
    Well, the professor of this unit tells to use only what he already referred to in his documents... The vector part of the book was never referred to yet, so I'm not supposed to use it. If I had to do this for real life application I'd already have used vectors or anything simpler than all this. I'll ask if I can do it with vectors... Maybe he won't mind.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    If you cannot, then you could always pick a simpler task, then? Can you not?
    This is not a suitable beginner's program and this is C-style complexity, which you do not really have to worry about in a C++ program.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by SaTaNaMa View Post
    Oh sorry for the line number, I didn't copy the header ... :S The code actually started at line 13.




    Well, the professor of this unit tells to use only what he already referred to in his documents... The vector part of the book was never referred to yet, so I'm not supposed to use it. If I had to do this for real life application I'd already have used vectors or anything simpler than all this. I'll ask if I can do it with vectors... Maybe he won't mind.
    Well, what do you know, then? (And by "know", I mean "are allowed to use".) Are you required to use short**? (If so, then head over to the C forum, 'cause there's no "C++" way to do that, and search for dynamic two dimensional arrays.)

  10. #10
    Registered User
    Join Date
    Dec 2005
    Posts
    13
    Truth is that I didn't have to make it dynamically allocated, but since the max size of the matrices is 256*256, I thought it wasn't so good to always automatically reserve 262 kB of RAM (for int) for a file weighting only 215 B ... So I thought I could allocate it dynamically and use short instead.

    Now I've done it with tables of type vector<vector<short>> and it looks like it works perfect... so if the professorial team doesn't mind, I'll keep it that way, else I'll just allocate the full 256*256. They specified they wanted a bidimensional array and a vector<vector<short>> is just about it anyway.

    I'll know Monday...

    Anyway, thanks to both of you.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM