472,337 Members | 1,520 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,337 software developers and data experts.

Array setup Question

Hello

I have the following defined structure

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /* increment value for item in
folder */
char *itemid; /* id of returned item */
int count; /*total count of array */
};
In the function I have this

struct cm8linkstruc **cm8link;

If I want to allocate 50 occurrences of this array then if the
following correct? It appears to be correct at least at a compile level
because it compiles

/*Allocate the array for use over in the dll */
cm8link = (struct cm8linkstruc **) malloc(50 * sizeof(struct
cm8linkstruc *));
for(h = 0; h< 50 ; h++)
{
cm8link[h] = (struct cm8linkstruc *) malloc(sizeof(struct
cm8linkstruc));
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
cm8link[h]->count = 0;
}

I have a function in a dll that will add values to the array and then
pass the populated array back to the calling exe

If I am on the right track then would I pass &cm8link to my function in
my dll in order to use it to populate it before I return from the
called function?

Thanks
Jake

Mar 20 '06 #1
7 1565
Jake Thompson wrote:
Hello

I have the following defined structure

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /* increment value for item in
folder */
char *itemid; /* id of returned item */
int count; /*total count of array */
};
In the function I have this

struct cm8linkstruc **cm8link;

If I want to allocate 50 occurrences of this array then if the
following correct? It appears to be correct at least at a compile level
because it compiles

/*Allocate the array for use over in the dll */ As soon as you say `dll', it's either irrelevant -- or off topic in this
newsgroup. cm8link = (struct cm8linkstruc **) malloc(50 * sizeof(struct
cm8linkstruc *)); Better:
cm8link = malloc(sizeof *cm8link * 50);

Since malloc() returns a pointer to void and such pointer is convertible
to any pointer to object the cast is unnecessary -- and should be
avoided (it can hide, for example, the failure to include <stdlib.h>.

Further, using the `sizeof object' form is often preferable to the
`sizeof(type)' form; it the type happens to be changed, it makes for one
less change that need be made...
and, of course, make sure the malloc() succeeded. for(h = 0; h< 50 ; h++)
{
cm8link[h] = (struct cm8linkstruc *) malloc(sizeof(struct
cm8linkstruc)); Better:
cm8link[h] = malloc(sizeof **cm8link);
and, of course, make sure the malloc() succeeded cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
cm8link[h]->count = 0;
}

I have a function in a dll that will add values to the array and then
pass the populated array back to the calling exe

If I am on the right track then would I pass &cm8link to my function in
my dll in order to use it to populate it before I return from the
Again either this `dll' stuff is irrelevant or off topic.
called function?

HTH,
--ag
--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
"You can't KISS* unless you MISS**"
[*-Keep it simple, stupid. **-Make it simple, stupid.]
Mar 20 '06 #2
On 2006-03-20, Jake Thompson <re***********@hotmail.com> wrote:
Hello

I have the following defined structure

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /* increment value for item in
folder */
char *itemid; /* id of returned item */
int count; /*total count of array */
};
In the function I have this

struct cm8linkstruc **cm8link; ... /*Allocate the array for use over in the dll */
cm8link = (struct cm8linkstruc **) malloc(50 * sizeof(struct
cm8linkstruc *));
for(h = 0; h< 50 ; h++)
{
cm8link[h] = (struct cm8linkstruc *) malloc(sizeof(struct
cm8linkstruc));
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
cm8link[h]->count = 0;
}
This looks all right, although you should do something if the
allocations fail, and it isn't necessary to cast the return of malloc.

Make sure you free the whole lot in the right way too when the time
comes.
I have a function in a dll that will add values to the array and then
pass the populated array back to the calling exe If I am on the right track then would I pass &cm8link to my function
in my dll in order to use it to populate it before I return from the
called function?


It sounds like &cm8link is one too many levels of indirection than you
need. Could you not just pass cm8link?

Then the function in the dll populates the array like this:

for (i = 0; i < 50; i++)
{
cm8link[i]->desc = something;
...
}
Mar 20 '06 #3
On 2006-03-20, Jake Thompson <re***********@hotmail.com> wrote:
struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /* increment value for item in
folder */
char *itemid; /* id of returned item */
int count; /*total count of array */
};
In the function I have this

struct cm8linkstruc **cm8link;

/*Allocate the array for use over in the dll */
cm8link = (struct cm8linkstruc **) malloc(50 * sizeof(struct
cm8linkstruc *));
for(h = 0; h< 50 ; h++)
{
cm8link[h] = (struct cm8linkstruc *) malloc(sizeof(struct
cm8linkstruc));
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
cm8link[h]->count = 0;
}


I just said this "looked all right", but is there actually any reason
why you need an array of 50 pointers to individually allocated structs?

A typical reason to do that is if the "structs" are of variable sizes
that are determined later. But here they're not, they're all just sizeof
(cm8linkstruc).

So why not just allocate one array?

struct cm8linkstruc *cm8links =
malloc(50 * sizeof (struct cm8linkstruc));

for (h = 0; h < 50; h++)
{
cm8links[h].type = 0;
/* etc... */
}
Mar 21 '06 #4
Jake Thompson wrote:
Hello

I have the following defined structure

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /* increment value for item in
folder */
char *itemid; /* id of returned item */
int count; /*total count of array */
};
In the function I have this

struct cm8linkstruc **cm8link;

If I want to allocate 50 occurrences of this array then if the
following correct? It appears to be correct at least at a compile level
because it compiles
It would be easier if you provided a complete compilable example. For
example, I don't know whether you failed to include stdlib.h (which
without any other declaration for malloc in scope would give you
undefined behaviour) or merely failed to include it in your snippet.

#include <stdlib.h>
/*Allocate the array for use over in the dll */
cm8link = (struct cm8linkstruc **) malloc(50 * sizeof(struct
cm8linkstruc *));
*Never* cast the return value of malloc. See
http://c-faq.com/malloc/mallocnocast.html

You should also check the rest of the FAQ it has a lot of useful material.

cm8link = malloc(50 * sizeof *cm8link);

The above is much simpler, and saves having to count stars to see if you
got it right.

You should also check the return value. malloc can fail.
for(h = 0; h< 50 ; h++)
{
cm8link[h] = (struct cm8linkstruc *) malloc(sizeof(struct
cm8linkstruc));
See above.
cm8link[h] = malloc(sizeof *(cm8link[h]));

Again, check to see if malloc succeeded.
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
cm8link[h]->count = 0;
}

I have a function in a dll that will add values to the array and then
pass the populated array back to the calling exe

If I am on the right track then would I pass &cm8link to my function in
my dll in order to use it to populate it before I return from the
called function?


Since you don't give a complete compilable example I'm not entirely sure
what you are trying to do. However, perhaps you should read
http://c-faq.com/ptrs/passptrinit.html

In fact, you should probably start off by reading all of sections 3, 6
and 7 of the FAQ. You will probably find all of your answers there.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 21 '06 #5
Hello guys I made the following changes to my code based upon what I
read and the input that you guys gave me

my structure with all char * values

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /*increment value for item
in folder */
char *itemid; /* id of returned item */
};

struct cm8linkstruc cm8link;

Sample of code

/*Allocate the structure */
cm8link = malloc(sizeof cm8link * fcount);
if(!cm8link)
{
return 1;
}

for(h = 0; h< fcount ; h++)
{
cm8link[h] = malloc(sizeof (cm8link[h]));
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
}
l_stat = u_cm8_getfolditemmatch((PITEMID)cptr, &cm8link);
if(l_stat)
{
/*clean it structure and free it*/
for(h = 0; h< fcount ; h++)
{
u_free_uni(cm8link[h]->type);
u_free_uni(cm8link[h]->desc);
u_free_uni(cm8link[h]->item_increment);
u_free_uni(cm8link[h]->itemid);
free(cm8link[h]);
}
return(1);
}
Originally I was going to make the cm8linkstruc part of another
structure like this

struct cm8rcstruc
{
BOOLEAN checkedout; /* status of checked
out object*/
char *userid; /* user who has object
checked out */
short objtype; /* True is a folder
\False is not */
char *note; /* Returned note */
struct cm8linkstruc *u_cm8link; /*pointer to link
structure*/
};

That is why I had so many stars. I since changed my mind and just want
to make the cm8linkstruc it's own structure without being part of
another structure. By doing that I believe my indirection gets messed
up

so instead of defining the structure as
struct cm8linkstruc **cm8link;
I now define it as
struct cm8linkstruc cm8link;

which like I said messes up my indirection for my mallocs correct. How
can I fix this?

Also when doing the free of the structure I free each char * in the
array. This to me means that I have to allocate the char * in a
similar fashion which I am not currently doing because all I do on the
allocation is set everything to 0 when I think I should be doing
something more involved - Can someone show me an example?

Sorry for all the questions but I derailed very easy with allocations
and indirections and I am just trying to get back on track.

Thanks
Jake

Mar 21 '06 #6
"Jake Thompson" <re***********@hotmail.com> writes:
Hello guys I made the following changes to my code based upon what I
read and the input that you guys gave me

my structure with all char * values

struct cm8linkstruc
{
char *type; /* type of item*/
char *desc; /* description of item */
char *item_increment; /*increment value for item
in folder */
char *itemid; /* id of returned item */
};

struct cm8linkstruc cm8link;
Ok, cm8link is a struct object.
Sample of code

/*Allocate the structure */
cm8link = malloc(sizeof cm8link * fcount);
You're assigning the result of malloc() (a pointer) to a structure
object. That doesn't make any sense.

You probably want cm8link to be a pointer to struct:

struct cm8linkstruc *cm8link;

(You might want a different name for it, but I'll leave the name
alone.)

You can then allocate an array of "fcount" structures like this:

cm8link = malloc(sizeof *cm8link * fcount);

Note carefully that it's "sizeof *cm8link", not "sizeof cm8link".
if(!cm8link)
{
return 1;
}
Good, you're checking whether the malloc() succeeded. I presume
returning 1 from whatever function this code is part of makes sense.
(If the code is in main() then (a) it probably shouldn't be, and (b)
"return 1;" is not a portable way to indicate an error; use
EXIT_FAILURE, defined in <stdlib.h>.)
for(h = 0; h< fcount ; h++)
{
cm8link[h] = malloc(sizeof (cm8link[h]));
If cm8link is a pointer, then cm8link[h] is a struct; again, you're
assigning a pointer value to a struct object, which doesn't make any
sense. (And you're not checking whether the malloc() succeeded.)

If you want to allocate "fcount" structures, just allocate them all as
an array. You could allocate an array of pointers, and then allocate
each structure individually, but there doesn't seem to be any reason
to do so.

Decide what you want to allocate, and how you want to allocate it.
Drawing pictures on paper with boxes and arrows can be helpful (boxes
represent structures, arrows represent pointers).
cm8link[h]->type = 0;
cm8link[h]->desc = 0;
cm8link[h]->item_increment = 0;
cm8link[h]->itemid = 0;
You're setting each char* member to 0, i.e., a null pointer. (I'd use
NULL rather than 0.)
}
l_stat = u_cm8_getfolditemmatch((PITEMID)cptr, &cm8link);
No idea what this does.
if(l_stat)
{
/*clean it structure and free it*/
for(h = 0; h< fcount ; h++)
{
u_free_uni(cm8link[h]->type);
u_free_uni(cm8link[h]->desc);
u_free_uni(cm8link[h]->item_increment);
u_free_uni(cm8link[h]->itemid);
free(cm8link[h]);
I have no idea what u_fre_uni does.
}
return(1);
}

[...]

malloc() can allocate either a single object or a contiguous array of
objects; you just need to tell it how many bytes to allocate. It's
important to have a mental picture of what your data structure looks
like; as I wrote above, paper diagrams can be helpful here. Always
check the result of malloc(). Your program needs to call free() once
for each call to malloc() (that doesn't necessarily mean that that
exactly one call to free() will appear in your source for each
malloc() call in your source, but it often does.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Mar 21 '06 #7
> [...]
Also when doing the free of the structure I free each char * in the
array. This to me means that I have to allocate the char * in a
similar fashion which I am not currently doing because all I do on the
allocation is set everything to 0 when I think I should be doing
something more involved - Can someone show me an example?
If you call free with NULL, nothing happens, so this is OK, as it
stands. If you want to actually store data (strings probably) using
those char pointers, there will need to be some memory somewhere.

If you want to make those pointers point to strings somewhere else your
program, you may decide to make them point to newly allocated blocks
Sorry for all the questions but I derailed very easy with allocations
and indirections and I am just trying to get back on track.


It is difficult to understand exactly what things in particular it is
you're having problems with.

I would suggest get clear in your mind _first_ how things should be laid
out in memory and when they should be allocated and deallocated. Then
sort out the code that reads and writes them, because it won't be
difficult to make it work with whatever layout you decide on. I wonder
if your problem isn't that you're trying to build a data layout that
matches some other code you already have, but that could easily be
changed.

Here is a test program in case any part of it is any use:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct link
{
char *type;
char *name;
};

#define FCOUNT 4

int main(void)
{
int i;
struct link *p;

/* Allocate FCOUNT links in one array */
struct link *links = malloc(FCOUNT * sizeof (*links));
/* remember to check allocation */

/* Initially they have no name or type */
for (i = 0; i < FCOUNT; i++)
{
links[i].type = NULL;
links[i].name = NULL;
}

/*
* How to copy a string into one of the links' fields. You may not have
* strdup on your system, but you probably do.
*/
links[2].type = strdup("hello");
/* remember to check allocation */

/* How to get a pointer to an individual link */
p = links + 2;

printf("%s world\n", p->type);

/* Free the contents of any links that have contents. */
for (i = 0; i < FCOUNT; i++)
{
free(links[i].type); /* links[i].type may or may not be NULL */
free(links[i].name);
}

free(links);

return 0;
}

HTH
Mar 22 '06 #8

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

Similar topics

12
by: James | last post by:
Hi, Have posted before, but will simplify problem here. For original post go to http://forums.devshed.com/t80025/s.html I have setup 2 arrays...
9
by: Randell D. | last post by:
Folks, I can program fairly comfortably in PHP and can, for the most part using these skills and others that I've picked up over the years manage...
8
by: Peter B. Steiger | last post by:
The latest project in my ongoing quest to evolve my brain from Pascal to C is a simple word game that involves stringing together random lists of...
5
by: Stijn van Dongen | last post by:
A question about void*. I have a hash library where the hash create function accepts functions unsigned (*hash)(const void *a) int (*cmp)...
7
by: Sam | last post by:
Hello I have a structure called Company. struct Company { char *employee; char *employee_address; }; I want to build an array of this...
10
by: Generale Cluster | last post by:
Hello, I have the following situation: $list is an array of MyElement objects. MyElement has two members: MyElement->member1;...
0
by: blainegray | last post by:
Greetings This is one of those Access is not closing Excel problems. The first time through the code works fine. The second time there is a...
6
beacon
by: beacon | last post by:
Hi everybody, I asked my professor for some practice problems to work on over the summer to prep me for Data Structures this fall and he gave me...
5
by: barcrofter | last post by:
I have two independent arrays and mysteriously they occupy the same space. Is this an error or a feature? Dim tokens$() '(input...
0
by: concettolabs | last post by:
In today's business world, businesses are increasingly turning to PowerApps to develop custom business applications. PowerApps is a powerful tool...
0
by: Kemmylinns12 | last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
0
by: CD Tom | last post by:
This happens in runtime 2013 and 2016. When a report is run and then closed a toolbar shows up and the only way to get it to go away is to right...
0
by: CD Tom | last post by:
This only shows up in access runtime. When a user select a report from my report menu when they close the report they get a menu I've called Add-ins...
0
by: Naresh1 | last post by:
What is WebLogic Admin Training? WebLogic Admin Training is a specialized program designed to equip individuals with the skills and knowledge...
0
by: antdb | last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine In the overall architecture, a new "hyper-convergence" concept was...
0
by: AndyPSV | last post by:
HOW CAN I CREATE AN AI with an .executable file that would suck all files in the folder and on my computerHOW CAN I CREATE AN AI with an .executable...
0
by: Arjunsri | last post by:
I have a Redshift database that I need to use as an import data source. I have configured the DSN connection using the server, port, database, and...
0
hi
by: WisdomUfot | last post by:
It's an interesting question you've got about how Gmail hides the HTTP referrer when a link in an email is clicked. While I don't have the specific...

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.