473,763 Members | 1,356 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Access to data into an array causes seg-fault

I had a program that worked perfectly, and that read .wav files. I
changed something so the tags of the wave file, instead of being each
in a different variable, are all in an array, called tag. i also set
macros such as #define bitspersample tag[10] so when in my original
program it was written bitspersample now it acts like its tag[10], and
i also moved things that were in the main function into specific
functions. anyways, the program read the sound data into a multi
dimensionnal array.

now, since i did that change, when i try to access a value from that
multi-dimensional array by doing for example printf("%f",
sound[0][69]); in the main function, it causes a segmentation fault at
this precise line.

i think the multi-dimensionnal array is correctly allocated (the
difference between the old and new program is that the whole allocation
thing is in a function instead of the main function, and that it's
bases on values from that tag array to define its sizes instead of
regular integer variables)

now, i can access to a value of this multidimensiona l array, inside the
function that fills it, and also in the function that calls that
function and that allocates the array before calling it, but not back
in the main function.

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?

Nov 15 '05 #1
8 1926
On Sun, 03 Jul 2005 06:52:45 -0700, Michel Rouzic wrote:

....
now, i can access to a value of this multidimensiona l array, inside the
function that fills it, and also in the function that calls that
function and that allocates the array before calling it, but not back
in the main function.

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?


There's nothing wrong with that as long as sound is set correctly to point
to the memory allocated in the called funciton.

It sounds like there is a problem with your particualr code but we can't
tell what that might be without seeing it.

Lawrence
Nov 15 '05 #2


Michel Rouzic wrote:

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?


How are you returning the array to main? Are you passing it as a
parameter to the allocating function? If so, are you passing it as
double **sound or double ***sound?

Nov 15 '05 #3


John Bode wrote:
Michel Rouzic wrote:

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?


How are you returning the array to main? Are you passing it as a
parameter to the allocating function? If so, are you passing it as
double **sound or double ***sound?


well, in main(), i declare it as double **sound, then call my
allocating function by wav_in(double **sound, ...) and inside that
wav_in function i allocate by doing this :

sound=(double **) malloc (channels * sizeof(double *));
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);

then i call a function called in_32(double **sound,...) which fills
that array, and then well the array returns by the same way it came in,
the problem is that back to main() i cant access values of my array

Nov 15 '05 #4


Lawrence Kirby wrote:
On Sun, 03 Jul 2005 06:52:45 -0700, Michel Rouzic wrote:

...
now, i can access to a value of this multidimensiona l array, inside the
function that fills it, and also in the function that calls that
function and that allocates the array before calling it, but not back
in the main function.

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?


There's nothing wrong with that as long as sound is set correctly to point
to the memory allocated in the called funciton.

It sounds like there is a problem with your particualr code but we can't
tell what that might be without seeing it.

Lawrence


ok, im not sure if its very appropriate to paste code here, but here it
is anyways (i made it minimalistic to show whats the problem, would'nt
have pasted the whole 16 kB code)

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define formattag tag[5]
#define channels tag[6]
#define samplespersec tag[7]
#define bitspersample tag[10]
#define datasize tag[12]
#define samplecount tag[13]

void in_32(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t i, ic;
float temp;

for (i=0;i<sampleco unt;i++)
for (ic=0;ic<channe ls;ic++)
{
fread(&temp, sizeof(float), 1, wavin);
sound[ic][i]=(double) temp;
}
}

void wav_in(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t ic;

samplecount=dat asize/(bitspersample/8)/channels;

sound=(double **) malloc (channels * sizeof(double *));
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);

in_32(wavin, sound, tag);
fclose(wavin);
}

int main(int argc, char *argv[])
{
FILE *wavin;
wavin=fopen(arg v[1], "rb");
if (wavin)
{
uint32_t tag[14];
double **sound;

wav_in(wavin, sound, tag);

printf("%f ", sound[0][69]); //that's where the seg fault happens
return 0;
}
}

Nov 15 '05 #5
Michel Rouzic wrote:
is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?
There's nothing wrong with that as long as sound is set correctly to point
to the memory allocated in the called funciton.

Michel, this is were you went wrong. The 'sound' variable Lawrence Kirby
is refering to is the one declared in the main() function. See below.
void wav_in(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t ic;

samplecount=dat asize/(bitspersample/8)/channels;

sound=(double **) malloc (channels * sizeof(double *));
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);

in_32(wavin, sound, tag);
fclose(wavin); <Personal note>: I would rather close a file in the same scope that I
opened it. But, hey, its your call :-) }

int main(int argc, char *argv[])
{
FILE *wavin;
wavin=fopen(arg v[1], "rb");
if (wavin)
{
uint32_t tag[14];
double **snd; Renamed 'sound' to 'snd' for ease of explantion.
wav_in(wavin, snd, tag);

printf("%f ", snd[0][69]); //that's where the seg fault happens
return 0;
}
}

The basic idea of passing a pointer to a function is to be able to
manipulate the _contents_ of the address pointed to by the pointer, not
the _pointer_ itself.

Suppose, 'snd' points to address location 1000. When you call the
wav_in() function, the 'sound' parameter is also set to point to address
location 1000. Within the wav_in() func when you allocate space and set
'sound' to point to it, 'snd' still points to 1000! Point to note: C has
only 'call by value' and no 'call by reference', i.e. any changes in
value to a passed variable within a function is not reflected in the
variable in caller's scope. Hope this makes sense. Maybe someone here
who has access to the standard can direct you to the appropriate section
(and direct me as to where I can download a copy of it :-] ).

Anyway, you can pass it as 'double ***sound' and do (*sound)=malloc ()
and (*sound)[ic]=malloc().

Or, you can change the code as follows:
double **wav_in(FILE *wavin, uint32_t *tag)
{
double **sound;
/*
* rest of your code (incl. allocations)
*/
return sound;
}

and in main()
double **sound;
sound = wav_in(wavin, tag);
cheers,
forayer
Nov 15 '05 #6
In article <11************ *********@f14g2 000cwb.googlegr oups.com>
Michel Rouzic <Mi********@yah oo.fr> wrote:
ok, im not sure if its very appropriate to paste code here ...
It is; especially something cut down to show just the problem, as
you did! :-)
#include <stdio.h>
#include <stdint.h>
#include <math.h>
[snippage]
void wav_in(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t ic;

samplecount=dat asize/(bitspersample/8)/channels;

sound=(double **) malloc (channels * sizeof(double *));
As someone else already noted, the most significant problem here is
that you pass in a value, which wav_in() copies to its local variable
named "sound"; then you overwrite the passed-in value with a new
value from malloc(); then you return, discarding the overwritten
local variable. The caller's version of the variable named "sound"
is not changed.

Another bug is that you used casts above, and here:
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);


You probably put in this cast because without it you got a message
of the form:

warning: assignment makes pointer from integer without cast

(more or less). But inserting the cast merely removes the warning,
without fixing the bug. The actual bug is forgetting to include
<stdlib.h>, which is how you tell the C compiler that malloc() has
"void *" as its return type. Without this, your C compiler would
see malloc() here for the first time and, in effect, think: "oh,
that must be a function that returns an int. I will just pretend
I saw:

int malloc();

before this point." Of course, this is the wrong declaration, and
if it works anyway, it is just by luck.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #7
On Sun, 03 Jul 2005 18:35:12 -0700, Michel Rouzic wrote:


Lawrence Kirby wrote:
On Sun, 03 Jul 2005 06:52:45 -0700, Michel Rouzic wrote:

...
> now, i can access to a value of this multidimensiona l array, inside the
> function that fills it, and also in the function that calls that
> function and that allocates the array before calling it, but not back
> in the main function.
>
> is it a problem due to declaring such a "double **sound" array in the
> main function and doing the malloc's in another function?
There's nothing wrong with that as long as sound is set correctly to point
to the memory allocated in the called funciton.

It sounds like there is a problem with your particualr code but we can't
tell what that might be without seeing it.

Lawrence


ok, im not sure if its very appropriate to paste code here, but here it
is anyways (i made it minimalistic to show whats the problem, would'nt
have pasted the whole 16 kB code)


Yes, posting minimal code is very appropriate.
#include <stdio.h>
#include <stdint.h>
#include <math.h>
#define formattag tag[5]
#define channels tag[6]
#define samplespersec tag[7]
#define bitspersample tag[10]
#define datasize tag[12]
#define samplecount tag[13]

void in_32(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t i, ic;
float temp;

for (i=0;i<sampleco unt;i++)
for (ic=0;ic<channe ls;ic++)
{
fread(&temp, sizeof(float), 1, wavin);
sound[ic][i]=(double) temp;
}
}
First note what you are doing with sound here. It is a value passed into
the function which is used to access an array. That's fine.
void wav_in(FILE *wavin, double **sound, uint32_t *tag)
{
uint32_t ic;

samplecount=dat asize/(bitspersample/8)/channels;

sound=(double **) malloc (channels * sizeof(double *));
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);

in_32(wavin, sound, tag);
fclose(wavin);
}
Here wav_in is also defined to take a double ** argument for sound.
However it discards the value passed in and sets the local sound variable
to a new value. C passes arguments "by value" which means that the called
function gets a copy of the value, and the parameter variable within it is
independent of the caller. So any changes you make to sound within wav_in
are not visible outside the function.

There is another problem with the code i.e. calling malloc() without a
valid declaration in scope. You can correct that by including the
appropriate header which is <stdlib.h> in this case. You made the mistake
of casting the return value of malloc(). If you hadn't done this the
compiler would have warned you about the problem.
int main(int argc, char *argv[])
{
FILE *wavin;
wavin=fopen(arg v[1], "rb");
if (wavin)
{
uint32_t tag[14];
double **sound;

wav_in(wavin, sound, tag);
These 2 lines can never be correct. You have defined an uninitialised
variable sound and then you pass the value of this uninitialised variable
to wav_in(). Acessing the value of an uninitialised variable is always an
error, although the effects tend to be nastier when the variable is a
pointer. What you need is code that updates the value of sound in main()
from wav_in. The most natural way is using a return value from the
function:

double **sound;

sound = wav_in(wavin, tag);

which you could write simply as

double **sound = wav_in(wavin, tag);

and then in wav_in make sound a simple local variable and return it.

You can also update the value of an object in the caller by passing a
pointer to it:

void wav_in(FILE *wavin, double ***soundret, uint32_t *tag)
{
uint32_t ic;
double **sound;

samplecount=dat asize/(bitspersample/8)/channels;

sound = malloc (channels * sizeof *sound);
for (ic=0;ic<channe ls;ic++)
sound[ic] = malloc (samplecount * sizeof *sound[ic]);

in_32(wavin, sound, tag);
fclose(wavin);

*soundret = sound;
}

This uses a pointer to pointer to pointer to double (double ***) but
there's no need to worry about that, it is simply a type that can point at
a pointer to pointer to double (double **). In the caller you would use:

double **sound;

wav_in(wavin, &sound, tag);
printf("%f ", sound[0][69]); //that's where the seg fault happens


In your original code sound is still uninitialised at this point so
accessing its value as this code does is an error.

Lawrence
Nov 15 '05 #8


Michel Rouzic wrote:
John Bode wrote:
Michel Rouzic wrote:

is it a problem due to declaring such a "double **sound" array in the
main function and doing the malloc's in another function?
How are you returning the array to main? Are you passing it as a
parameter to the allocating function? If so, are you passing it as
double **sound or double ***sound?


well, in main(), i declare it as double **sound, then call my
allocating function by wav_in(double **sound, ...) and inside that
wav_in function i allocate by doing this :

sound=(double **) malloc (channels * sizeof(double *));
for (ic=0;ic<channe ls;ic++)
sound[ic]=(double *) malloc (sizeof(double) * samplecount);


Here's your problem. Remember that in order to write to a parameter,
you must pass a pointer to that parameter. If you want to assign a
pointer value in your allocating function and have that change
reflected in main(), then you need to pass a pointer to the pointer.

In this specific case, you have a double** that you want to assign, so
you need to pass a pointer to it:

double **sound;
wav_in(&sound, ...);

void wav_in(double ***sound, ...)
{
...
*sound = malloc(sizeof (*sound)[0] * channels);
if (*sound)
{
for (ic=0; ic<channels; ic++)
{
(*sound)[ic] = malloc(sizeof (*sound)[ic][0] *
samplecount);
...
}
in_32(*sound,.. .);
}

Remember, don't cast the result of malloc(), and I've found it's a good
idea to use sizeof on the *object* you're allocating, rather than a
type. IOW, since we're allocating an array of T, use sizeof on an
array element, rather than sizeof T itself. Since the type of sound is
double ***, then the type of *sound is double **, the type of
(*sound)[0] is double*, and the type of (*sound)[0][0] is double, so

malloc(sizeof (*sound)[0] * N)

will allocate N elements of type double*, and

malloc(sizeof (*sound)[0][0] * N)

will allocate N elements of type double.
then i call a function called in_32(double **sound,...) which fills
that array, and then well the array returns by the same way it came in,
the problem is that back to main() i cant access values of my array


The call to in_32 works because you aren't trying to modify the value
of sound itself, just the array elements that sound points to.

Again, remember that if you want to write to a parameter in a function
and have that change reflected in the calling function, you have to
pass a pointer to that parameter.

Personally, when I write allocator functions, I return the thing being
allocated as the function return value. IOW, I'd write it like this:

double **newSoundArray (...)
{
double **sound;
...
sound = malloc(sizeof sound[0] * channels);
if (sound)
{
for (ic = 0; ic < channels; ic++)
{
sound[ic] = malloc (sizeof sound[ic][0] * samplecount);
...

return sound;
}

int main(void)
{
double **sound;

sound = newSoundArray(. ..);
...
}

Less dereferencing hell this way.

Nov 15 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
4357
by: Lost Bits | last post by:
Hello there C++ pros.. Well, I have recently redesigned an already existing piece of code that someone else designed - its just a search algorithm they developed, and has to perfomr millions of loops depending on the data input.. My problem is that my code can be upto 10 times slower than the previous persons - and speed is very critical. (and I dont mean setting up the arrays takes long, I'm more concernted about the speed
6
4114
by: blueblueblue2005 | last post by:
here is a friend function of Class Array, which has two private data member: int size, int *ptr // Array's public member function to return size int getSize() const { return size; } friend istream &operator>>(istream &in, Array &a) { for(int i=0; i<a.size; i++) // do something
3
24035
by: Random Person | last post by:
Does anyone know how to use VBA to relink tables between two MS Access databases? We have two databases, one with VBA code and the other with data tables. The tables are referenced by linked tables in the database where the code resides. If we move the database with the data tables to a new directory, the links are no longer valid. I tried to update the links by changing the Connect property and refreshing: Set td = db.TableDefs(0)...
7
8869
by: dog | last post by:
I've seen plenty of articles on this topic but none of them have been able to solve my problem. I am working with an Access 97 database on an NT4.0 machine, which has many Access reports. I want my users to be able to select a report, click on a command button on a form, which will then automatically create the report as a pdf file and save it to the user's machine. I am using Adobe Acrobat (5.0 I think) and have Adobe Distiller as a
11
6600
by: Grasshopper | last post by:
Hi, I am automating Access reports to PDF using PDF Writer 6.0. I've created a DTS package to run the reports and schedule a job to run this DTS package. If I PC Anywhere into the server on where the job is running, the job runs sucessfully, PDF files got generated, everything is good. If I scheduled the job to run at the time that I am not logged into the server, Access is not able to print to the printer. The error is pretty...
2
2196
by: david | last post by:
Well, as a matter of fact I_HAD_MISSED a basic thing or two, anyway, although Ollie's answer makes perfectly sense when dealing with classes, it doesn't seem to me to apply as well if you have to instantiate an array of structures; consider the following useless code : using System; struct MyPointS
7
4778
by: Martin Strojek | last post by:
Hi, I have the following problem with developing some web site. I use Visual Studio 2003 to build a website. I tried Windows 2003 Server and switched now back to Windows XP with PWS but the error occurs in both installations. When I do a compile/build of my app and go to the browser and hit reload there comes an error:
4
2117
by: Mike | last post by:
I encountered this problem for the first time today while trying to add some columns to a query from a linked DBASEIII file. The new columns that I added on the design grid do not show up on the data sheet, even though the box is checked. I've already done some trouble shooting, making sure the box is checked, making sure that the columns aren't hidden. Also, I went to the toolbar menu, under tools and then options, and checked the...
2
2257
by: gellis72 | last post by:
I'm working on a program that imports a bunch of data from a folder full of Excel files and compiles it into an Access DB. The Excel files have a varying number of rows and columns that need to be imported, and the data needs to be processed/error checked before it's written to the DB. The way I've tackled this is to have a procedure that steps through a list of Excel files, invokes an instance of Excel, opens file "x", copies the relevant...
2
19488
hyperpau
by: hyperpau | last post by:
Before anything else, I am not a very technical expert when it comes to VBA coding. I learned most of what I know by the excellent Access/VBA forum from bytes.com (formerly thescripts.com). Ergo, I will be writing this article intended for those who are in the same level, or maybe lower, of my technical knowledge. I would be using layman's words, or maybe, my own words as how I understand them, hoping, you will understand it the same way that...
0
9563
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9386
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9998
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9822
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6642
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5270
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5406
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
3523
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2793
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.