NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.
To learn about what's going on, see About the Archive Site.
Hi JongKwan, float** snow_we is an array of float* pointers. This is the problem, put() requires a float pointer. The &[0][0] provides a float pointer, and the compiler thinks put() will be satisfied, but tricking the compiler does not make snow_we a contiguous array of floats. The tcount pointers in snow_we occupy a contiguous range of cells, but these cells hold memory addresses, not your data. Each address points to a (also contiguous) vector of floats, length npix, which contains one line of data values. But these vectors are independently located in memory, so snow_we as a whole is not contiguous. By specifying &[0][0], you give put() the address of the first cell in your fist data array, and NetCDF finds happily the first npix values located in snow_we[0][0..npix-1]. But then NetCDF just continues, looking for the next value in snow_we[0][npix]. This memory location doesn't even necessarily belong to your program. The value you want NetCDF to find is snow_we[1][0], but the address in snow_we[1] was never provided to NetCDF. You really need to allocate the array you provide to put() in one single operation whether you use C++ new or C malloc. In other words; while NetCDF treats the NcVar *data as a multi-dimensional array, the transfer buffer snow_we is (required to be) a single-dimensional vector. Hence, you must know how this buffer is interleaved, so that the dimensions are not mixed up in the transfer. BTW, since you have declared the NcVar *data as containing only two dimensions (xDim and yDim), each of your 20000 iterations will overwrite the previous data written to dataFile. Is this intended? If you really meant to store all the data, you must add a dimension for icall, which must be the first dimension Then, you can allocate a 20000*tcount*npix vector and do one call to data->put(snow_we,20000,tcount,npix), after set_cur(0,0,0) OR you can allocate a tcount*npix vector and do 20000 calls to data->put(snow_we,1,tcount,npix), each after set_cur(icall,0,0) OR you can allocate a npix vector and do 20000*tcount calls to data->put(snow_we,1,1,npix), each after set_cur(icall,count,0) Since you have declared snow_we as an array of float, not an array of float*, put() doesn't need the &[0][0] specification. Unless you are putting/getting the entire NcVar, you need to specify the offsets in each dimension. Thus only in the first case, you can get away with not using set_cur(), but I recommend you to always use this offset specification. In the last case, you can actually keep your current float** snow_we data structure, be sure to pass snow_we[count] as the first parameter to put(). This is a float pointer, and snow_we[count] is a contiguous array of floats. For time considerations, I'd recommend you allocate and de-allocate snow_we outside the icall-loop, since the size doesn't change. Good luck! Sjur K :-) ________________________________ From: netcdfgroup-bounces@xxxxxxxxxxxxxxxx [mailto:netcdfgroup-bounces@xxxxxxxxxxxxxxxx] On Behalf Of JongKwan Kim Sent: 31. mars 2010 00:09 To: netcdfgroup Subject: [netcdfgroup] netCDF C++ Library : writing in loop Hi all, I have a trouble in my code below. When I run this code, I have a segmentation fault in front of red line, even though the code is running until 4 times. That is, when the icall = 0, 1, 2, 3, the code is running well, but icall = 4, I have a segmentation fault. I guess the problem might be creating the netCDF files. Do you guys have any ideas to solve this problem... please let me know that. Thanks a lot. for (int icall=0; icall<20000; i++) {// for int iseed =1, tcount=14608, npix=108, error=2, count=0; float **snow_we, **soil_uztwc; snow_we = FloatMatrix2(tcount,npix); soil_uztwc = FloatMatrix2(tcount,npix); vector< float > we_val( npix ); vector< float > soil_val( npix ); while ( currentTime <= 14608) {//while count++; error = retrieve_value( allPixels, "we", we_val ); error = retrieve_value( allPixels, "real_soil", soil_val ); for (int j = 0; j < npix; j++) { snow_we[count-1][j] = we_val[j]; soil_uztwc[count-1][j] = soil_val[j]; } }//while char snowfname[50] = {0, }; sprintf(snowfname,"snow_scem_iseed%d_iter%d.nc<http://d.nc>",iseed,icall); NcFile dataFile(snowfname, NcFile::Replace); if (!dataFile.is_valid()) { cout << "Could not open the netcdf snow file ! \n " << endl; } NcDim* xDim = dataFile.add_dim("x",tcount); NcDim* yDim = dataFile.add_dim("y",npix); NcVar *data = dataFile.add_var("data",ncFloat,xDim,yDim); data->put(&snow_we[0][0],tcount,npix); char uztwcfname[50] = {0, }; sprintf(uztwcfname,"uztwc_scem_iseed%d_iter%d.nc<http://d.nc>",iseed,icall); NcFile dataFile2(uztwcfname, NcFile::Replace); if (!dataFile2.is_valid()) { cout << "Could not open the netcdf uztwc file ! \n " << endl; } NcDim* xDim2 = dataFile2.add_dim("x",tcount); NcDim* yDim2 = dataFile2.add_dim("y",npix); NcVar *data2 = dataFile2.add_var("data",ncFloat,xDim2,yDim2); data2->put(&soil_uztwc[0][0],tcount,npix); FreeFloatMatrix2 (snow_we,tcount); FreeFloatMatrix2 (soil_uztwc,tcount); }//for
netcdfgroup
archives: