Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > writing library functions and pointers?

Reply
Thread Tools

writing library functions and pointers?

 
 
Martin
Guest
Posts: n/a
 
      07-03-2009
Hi,

I have been trying to construct my own library of commonly used C
functions and have got a bit stuck and wonder if anyone could give me
any pointers?

I have set up a generic read function...

void read_file_float(FILE **fp, float **array, int size, char **argv)
{
if (fread(*array, sizeof (float), size, *fp) != size) {
fprintf(stderr, "Error reading in file: %s\n", *argv);
exit(1);
}
return;
}

which I call using the following in my code for example

FILE *fp;
float *array (which I allocate);
int numrows = something;
int numcols = something

read_file_float(&fp, &array, numrows * numcols, argv);

This works fine.

The problem comes when I do something similar but instead use fseek -
so in this instance i only want to read part of the file into the
array e.g. array[counter]

Now my call to the function would be

read_file_float(&fp, &array[some_counter]), 1, argv);

But I don't know how to declare this correctly.

Any thoughts?
Thanks in advance
 
Reply With Quote
 
 
 
 
Martin
Guest
Posts: n/a
 
      07-03-2009
I think I have solved it.

function needs to be declared differently

void read_seg_float(FILE **fp, float *array, int size, char **argv)
{
if (fread(array, sizeof (float), size, *fp) != size) {
fprintf(stderr, "Error reading in file: %s\n", *argv);
exit(1);
}
return;
}

and then accessed

read_seg_float(&fp, &array[some_counter], size, argv);
 
Reply With Quote
 
 
 
 
Nobody
Guest
Posts: n/a
 
      07-03-2009
On Fri, 03 Jul 2009 02:15:49 -0700, Martin wrote:

> I have been trying to construct my own library of commonly used C
> functions and have got a bit stuck and wonder if anyone could give me
> any pointers?
>
> I have set up a generic read function...
>
> void read_file_float(FILE **fp, float **array, int size, char **argv)


Why are you passing a FILE** rather than just a FILE*? And a float**
rather than just a float*?


 
Reply With Quote
 
Martin
Guest
Posts: n/a
 
      07-03-2009
On 3 July, 12:22, Nobody <(E-Mail Removed)> wrote:
> On Fri, 03 Jul 2009 02:15:49 -0700, Martin wrote:
> > I have been trying to construct my own library of commonly used C
> > functions and have got a bit stuck and wonder if anyone could give me
> > any pointers?

>
> > I have set up a generic read function...

>
> > void read_file_float(FILE **fp, float **array, int size, char **argv)

>
> Why are you passing a FILE** rather than just a FILE*? And a float**
> rather than just a float*?


because I understood the way adjust passed copy of pointer was to use
a pointer to a pointer. I got that from the FAQ, perhaps I
misunderstood?

http://c-faq.com/ptrs/passptrinit.html
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      07-03-2009
Martin wrote:
> On 3 July, 12:22, Nobody <(E-Mail Removed)> wrote:
>> On Fri, 03 Jul 2009 02:15:49 -0700, Martin wrote:
>>> I have been trying to construct my own library of commonly used C
>>> functions and have got a bit stuck and wonder if anyone could give me
>>> any pointers?
>>> I have set up a generic read function...
>>> void read_file_float(FILE **fp, float **array, int size, char **argv)

>>
>> Why are you passing a FILE** rather than just a FILE*? And a float**
>> rather than just a float*?

>
> because I understood the way adjust passed copy of pointer was to use
> a pointer to a pointer. I got that from the FAQ, perhaps I
> misunderstood?
>
> http://c-faq.com/ptrs/passptrinit.html


You're not changing the caller's pointer, only the object that the
pointer is pointing to.

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      07-03-2009
On Fri, 3 Jul 2009 03:25:31 -0700 (PDT), Martin <(E-Mail Removed)>
wrote:

>I think I have solved it.
>
>function needs to be declared differently
>
>void read_seg_float(FILE **fp, float *array, int size, char **argv)
>{
> if (fread(array, sizeof (float), size, *fp) != size) {
> fprintf(stderr, "Error reading in file: %s\n", *argv);
> exit(1);
> }
> return;
>}
>
>and then accessed
>
>read_seg_float(&fp, &array[some_counter], size, argv);


If you had compiled this with your calling function, you would see
that it is not correct. In the calling function, array is declared as
array of float*. Therefore, array[some_counter] is a particular
float*. Therefore, &array[some_counter] has type float**. Since the
second parameter in the definition of read_seg_float is a float*, this
is a constraint violation requiring a diagnostic. The compiler cannot
generate correct code for this even if it converts the value
&array[some_counter] to type float*.

--
Remove del for email
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      07-03-2009
On Fri, 3 Jul 2009 02:15:49 -0700 (PDT), Martin <(E-Mail Removed)>
wrote:

>Hi,
>
>I have been trying to construct my own library of commonly used C
>functions and have got a bit stuck and wonder if anyone could give me
>any pointers?
>
>I have set up a generic read function...
>
>void read_file_float(FILE **fp, float **array, int size, char **argv)
>{
> if (fread(*array, sizeof (float), size, *fp) != size) {
> fprintf(stderr, "Error reading in file: %s\n", *argv);
> exit(1);
> }
> return;
>}
>
>which I call using the following in my code for example
>
>FILE *fp;
>float *array (which I allocate);
>int numrows = something;
>int numcols = something
>
>read_file_float(&fp, &array, numrows * numcols, argv);


The unnecessary & applied to fp is discussed elsethread.

array is an object. A such, it is located in memory and has an
address. It also contains a value. Since it is a pointer object,
that value happens to be the address of an area of memory suitable for
holding a number of floats. &array evaluates to the address of the
object.

In your function, you immediately dereference this value. The result
of this operation is the contents of the pointer object which is the
location where you want to store data. Note that nowhere in your
function do you attempt to modify the contents of the pointer object
itself. Consequently, there is no need to pass the address of the
pointer to the function. Thus, the & applied to array is just as
unnecessary as the one applied to fp.

To answer your response in a subsequent message, yes you have
misunderstood slightly. Every argument passed to a function is passed
by value (as if a copy of the argument is passed to the function).
This is true whether the object is a number (integer or floating) or
an address. As a result of this, when the argument is a scalar
object, the function is incapable of modifying the value of the object
***in the calling function***. It is capable of modifying the local
copy that was passed but this is not the same as the original object.

Therefore, when the function needs to modify the object in the calling
function, one common technique is to pass the address of the object
(using the & operator). The function can then dereference this
address to get access to the object in the calling function.

However, this does not apply to your function because it us not
attempting to modify any of the arguments it is passed. fread never
updates the FILE* you pass it; it only updates the FILE the pointer
points to. Your code does not attempt to modify either copy of array,
only the memory that array in the calling function points to. While
the code you have will work, because you added the necessary
dereference operators, it is unnecessary. You can remove the &'s from
the calling statement and remove one * from every use of fp and array.

>
>This works fine.
>
>The problem comes when I do something similar but instead use fseek -
>so in this instance i only want to read part of the file into the
>array e.g. array[counter]
>
>Now my call to the function would be
>
>read_file_float(&fp, &array[some_counter]), 1, argv);
>
>But I don't know how to declare this correctly.


If you fix your function to expect a simple float* as described above,
this will magically be correct. If for some reason you have not
disclosed to us you really need the extra level of indirection, then
one method for reading a single value would be
float *x;
x = &array[some_counter];
read_file_float(&fp, &x, 1, argv);

--
Remove del for email
 
Reply With Quote
 
Martin
Guest
Posts: n/a
 
      07-03-2009
Hi thanks for all of the replies...

yes I guess a combination of me misunderstanding and because I
attempted to adapt the first function I wrote to allocate memory:

float *array;
int size = some_number;

void allocate_memory_float(float **array, int size, const unsigned int
line)
{
if (!(*array = (float *)calloc((size + 1), sizeof (float)))) {
check_errors("Error allocating enough memory for array", line);
}
return;
}

which I call:

allocate_memory_float(&array, size, __LINE__);

Which I think in this case as I am changing the array it is fine to
pass it like this? Just not for fread because I am not actually
changing anything?

Thanks again, the help really is appreciated.
 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      07-03-2009
On Fri, 3 Jul 2009 15:41:33 -0700 (PDT), Martin <(E-Mail Removed)>
wrote:

>Hi thanks for all of the replies...
>
>yes I guess a combination of me misunderstanding and because I
>attempted to adapt the first function I wrote to allocate memory:
>
>float *array;
>int size = some_number;
>
>void allocate_memory_float(float **array, int size, const unsigned int
>line)
>{
> if (!(*array = (float *)calloc((size + 1), sizeof (float)))) {


You don't need to cast the return from calloc. In fact, doing so can
cause the compiler to fail to warn you about some undefined behavior.

You also don't need the parentheses around size+1.

While using calloc does not cause any problems, it also doesn't
provide a portable benefit. It WILL set every byte of the allocated
memory to all-bits-zero. However, there is NO guarantee this
represents 0.0f or any other valid float value.

By the way, for messages posted to Usenet it is better to use spaces
than tabs to perform indenting. It eliminates problems due the
variety of newsreaders used.

> check_errors("Error allocating enough memory for array", line);
> }
> return;
>}
>
>which I call:
>
>allocate_memory_float(&array, size, __LINE__);
>
>Which I think in this case as I am changing the array it is fine to
>pass it like this? Just not for fread because I am not actually
>changing anything?


While this approach will work, the more common C idiom would be

#include <stdlib.h>
float* allocate_memory_float(int size, const unsigned int line)
{
float *ptr;
if (!(ptr = malloc((size + 1) * sizeof *ptr))) {
check_errors("Error allocating enough memory for array",
line);
}
return ptr;
}

which is called with
array = allocate_memory_float(size, __LINE__);

If you were willing to do the error checking in the calling function,
the entire body of allocate_memory_float could be replaced with
return malloc((size + 1) * sizeof *ptr);
which would basically eliminate the need for a separate function
entirely.

--
Remove del for email
 
Reply With Quote
 
Martin
Guest
Posts: n/a
 
      07-03-2009
Thanks a lot Barry I will adopt the form you suggested instead. Two
more questions if you have a moment

1.Do you have a suggestion for how I would write a function for the
allocation of my structure?

Currently I set a structure up

typedef struct {
int something;
int something_else;
} control;

in my .h file and then I allocate it in my code

control *c;
if ((c = (control *)malloc(sizeof (control))) == NULL) {
check_errors("Structure: Not allocated enough memory", __LINE__);
}

I don't know how I would set this up a library function

2. Also more a general question, currently I set up one big sturcture
and pass this around throughout my code. Do you suggest many smaller
structures would be better in practice? Does it matter? I guess the
later way reduces what is sent through the code, but does this
practically matter?

Thanks again
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Static functions and C++ member functions mafiQ C++ 0 04-22-2009 08:33 PM
Does ruby have a similar functions to the Python dir and help functions? py Ruby 5 03-24-2007 08:54 AM
private virtual functions and pure virtual functions with bodies John Goche C++ 10 12-08-2006 04:00 PM
Any problems with writing the information into a file - Multi-users perform writing the same file at the same time ???? HNguyen ASP .Net 4 12-21-2004 01:53 PM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM



Advertisments