C++ : trouble with arrays ?

Started by
9 comments, last by me22 18 years, 9 months ago
Hi, i'm trying to read a binary file containing integers, and then write the file in ascii mode. What i do is this: #define IDRISI_MAP_X 256 #define IDRISI_MAP_Y 256 unsigned int *idrisipMap = (unsigned int *) malloc( IDRISI_MAP_X * IDRISI_MAP_Y ); FILE *idrisi ; idrisi = fopen(project_texture , "rb" ); fread( idrisipMap, 1, IDRISI_MAP_X * IDRISI_MAP_Y, idrisi ); fclose(idrisi); // Finished reading file, now we start to write FILE *idrisi_out ; idrisi_out = fopen("C:\\temp\\idrisi_out.txt" , "w" ); for (int i=0; i<IDRISI_MAP_X * IDRISI_MAP_Y; i++) { fprintf(idrisi_out,"%i,", *idrisipMap++); // this crash the app when i goes > 16384 //fprintf(idrisi_out,","); This works filling the file with , } fclose(idrisi_out); I'm no expert, so i do not know how to use the debugger, and i dont understand what is the problem: seems to me i allocated the idrisipMap pointer correctly, but for some reasons it has an overflow. Thanks Alex
Advertisement
Interesting. From looking at your code, there is inconsistency where fprintf() expects int (%1) and the pointer is unsigned int.

Kuphryn
You need to specify the number of bytes to allocate when using malloc.
In this case, malloc(sizeof(unsigned int)*(IDRISI_MAP_X * IDRISI_MAP_Y)).
You'll also to specify the number of bytes when using fread.
as said before

unsigned int *idrisipMap = (unsigned int *) malloc( IDRISI_MAP_X * IDRISI_MAP_Y * sizeof(unsigned int) );


Malloc wants the number of bytes, and typically an int is 4 bytes.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Thanks guys, now the routine does not crash anymore.
However, i'm still no able to get the correct output.
The input file is a binary raster file which contains a sort of image map: values should go from 0 to 334.
Instead, the idrisi_out.txt is filled with 0's, while i was expecting to have several integer values ranging just from 0 to 334 as well.


Please title your post as "C: whatever" rather than "C++: whatever" if you are looking for help with C. If this really is supposed to be C++ code, then be aware that much nicer options that will avoid these kinds of mistakes have been available for many years in the standard library:

#include <iostream>// First, toss this in to your own library - it's an admitted shortcoming of the// new libraries, that comes from not wanting to assume that a chunk of // characters could be valid data if interpreted in other waystemplate <typename T>void readInto(std::istream& source, T* dest, unsigned int size) {  source.read(reinterpret_cast<char *>(dest), size * sizeof(T));  // We could use this manually too. Unfortunately we still have to worry about  // the type size, but we don't have to worry about separate "size of item"  // and "number of items" - actually this is a problem in your case; you want  // 'sizeof(unsigned int)' rather than '1' in your fread() call, AFAIK.}const unsigned int IDRISI_MAP_X = 256;const unsigned int IDRISI_MAP_Y = 256;const unsigned int IDRISI_SIZE = IDRISI_MAP_X * IDRISI_MAP_Y;unsigned int *idrisipMap = new unsigned int[IDRISI_SIZE];std::ifstream idrisi(project_texture, std::ios::binary);readInto(idrisi, idrisipMap, IDRISI_SIZE);// Don't need to close this; it will be close automatically at end of scope// but we can do it now, e.g. if we wanted to reopen the same file right away// like : idrisi.close();// Finished reading file, now we start to writestd::ofstream idrisi_out("C:/temp/idrisi_out.txt");// You can and should use forward slashes in filenames, even when that's not the// system file separator.for (int i=0; i < IDRISI_SIZE; i++) {  idrisi_out << idrisipMap << ",";  // No more messing about with format specifiers. The type of each item is  // checked at compile-time, and the appropriate code is generated to output  // each item in a formatted way. You could thus use either "," or ',' with  // identical effect.}// Don't forget to deallocate allocated memory! (Regardless of how it was// allocated - but the allocation and deallocation methods MUST match!)delete[] idrisipMap;// On the other hand, since the size is known statically, you don't need a // dynamic allocation, but should probably just use a static buffer instead :/

Quote:Original post by Zahlman
Please title your post as "C: whatever" rather than "C++: whatever" if you are looking for help with C. If this really is supposed to be C++ code, then be aware that much nicer options that will avoid these kinds of mistakes have been available for many years in the standard library:


You say that and yet you use new[] instead of std::vector and ignore standard algorithms =|

#include <iostream>#include <vector>// First, toss this in to your own library - it's an admitted shortcoming of the// new libraries, that comes from not wanting to assume that a chunk of // characters could be valid data if interpreted in other waystemplate <typename T>void readInto(std::istream& source, T* dest, unsigned int size) {  source.read(reinterpret_cast<char *>(dest), size * sizeof(T));  // We could use this manually too. Unfortunately we still have to worry about  // the type size, but we don't have to worry about separate "size of item"  // and "number of items" - actually this is a problem in your case; you want  // 'sizeof(unsigned int)' rather than '1' in your fread() call, AFAIK.}const unsigned int IDRISI_MAP_X = 256;const unsigned int IDRISI_MAP_Y = 256;const unsigned int IDRISI_SIZE = IDRISI_MAP_X * IDRISI_MAP_Y;std::vector<unsigned int> idrisipMap(IDRISI_SIZE);std::ifstream idrisi(project_texture, std::ios::binary);readInto(idrisi, &*idrisipMap.begin(), IDRISI_SIZE);// Don't need to close this; it will be close automatically at end of scope// but we can do it now, e.g. if we wanted to reopen the same file right away// like : idrisi.close();// Finished reading file, now we start to writestd::ofstream idrisi_out("C:/temp/idrisi_out.txt");// You can and should use forward slashes in filenames, even when that's not the// system file separator.copy( idrisipMap.begin(), idrisipMap.end(),      ostream_iterator<unsigned int>( idrisi_out, "," ) );// Who needs an explicit loop?// Note that std::vector is dealing with our memory for us, //  so we don't need to delete anything here!
Quote:Original post by me22
Quote:Original post by Zahlman
Please title your post as "C: whatever" rather than "C++: whatever" if you are looking for help with C. If this really is supposed to be C++ code, then be aware that much nicer options that will avoid these kinds of mistakes have been available for many years in the standard library:


You say that and yet you use new[] instead of std::vector and ignore standard algorithms =|

*** Source Snippet Removed ***
Whoa, easy there buddy! He was showing how new() is C++'s replacement for malloc(), not introducing him to the concept of vectors and algorithms in one fell swoop.
Still, your post is the next logical thing that could have been shown to the OP.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
You need to hear the smirk in me22's voice in his post. If you don't hear the smirk, you don't get it :).
Ok, let's go for the new libraries, but i got tons of errors ... please teach me ...

#include <windows.h>											// Header File For Windows#include <stdio.h>												// Header File For Standard Input / Output#include <stdarg.h>												// Header File For Variable Argument Routines#include <math.h>												// Header File For Math Operations#include <iostream>#include <algorithm>#include <string>#include <iostream>using namespace std;template <typename T>void readInto(std::istream& source, T* dest, unsigned int size) {source.read(reinterpret_cast<char *>(dest), size * sizeof(T));}const unsigned int IDRISI_MAP_X = 256;const unsigned int IDRISI_MAP_Y = 256;const unsigned int IDRISI_SIZE = IDRISI_MAP_X * IDRISI_MAP_Y;unsigned int *idrisipMap = new unsigned int[IDRISI_SIZE];std::ifstream idrisi("E:/temp/pippo.rst", std::ios::binary);readInto(idrisi, idrisipMap, IDRISI_SIZE);std::ofstream idrisi_out("C:/temp/idrisi_out.txt");for (int i=0; i < IDRISI_SIZE; i++) {  idrisi_out << idrisipMap << ",";}delete[] idrisipMap;


and these are the compile errors:

Compiling...
fileinput.cpp
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(21) : error C2079: 'idrisi' uses undefined class 'std::basic_ifstream<_Elem,_Traits>'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(21) : see reference to class template instantiation 'std::basic_ifstream<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(21) : see reference to class template instantiation 'std::basic_ifstream<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(21) : error C2078: too many initializers
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(22) : error C2501: 'readInto' : missing storage-class or type specifiers
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(22) : error C2365: 'readInto' : redefinition; previous definition was a 'function'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(12) : see declaration of 'readInto'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(22) : error C2078: too many initializers
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(24) : error C2079: 'idrisi_out' uses undefined class 'std::basic_ofstream<_Elem,_Traits>'
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(24) : see reference to class template instantiation 'std::basic_ofstream<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(24) : see reference to class template instantiation 'std::basic_ofstream<_Elem,_Traits>' being compiled
with
[
_Elem=char,
_Traits=std::char_traits<char>
]
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(24) : error C2440: 'initializing' : cannot convert from 'const char [23]' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2059: syntax error : 'for'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2143: syntax error : missing ')' before ';'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2143: syntax error : missing ';' before '<'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2501: 'i' : missing storage-class or type specifiers
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2143: syntax error : missing ';' before '++'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2501: 'i' : missing storage-class or type specifiers
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2086: 'int i' : redefinition
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : see declaration of 'i'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2059: syntax error : ')'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2143: syntax error : missing ';' before '{'
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(26) : error C2447: '{' : missing function header (old-style formal list?)
e:\Documents and Settings\terrestrial\Desktop\K-NN.source-lite\fileinput.cpp(30) : error C2059: syntax error : 'delete'

NeHe_OpenGL_Basecode - 18 error(s), 0 warning(s)

This topic is closed to new replies.

Advertisement