Wrap C primitive values in CFArray of CFNumbers - c

What is the best way to implement a method to wrap a C array of primitive numbers into a CFArray of CFNumbers?
I want to call something like:
double values[] = {1.2345, 678.9};
CFArrayRef arr = NumberWrappedValuesArray(&values, 2, kCFNumberDoubleType);
And tried this:
CFArrayRef NumberWrappedValuesArray(void * valueArrayPtr, CFIndex count, CFNumberType numberType) {
CFMutableArrayRef array = CFArrayCreateMutable(NULL, count, &kCFTypeArrayCallBacks);
for (int i = 0; i < count; i++) {
CFNumberRef numberWrappedValue = CFNumberCreate(NULL, numberType, &valueArrayPtr[i]);
CFArrayAppendValue(array, numberWrappedValue);
CFRelease(numberWrappedValue);
}
CFRelease(array);
return array;
}
It doesn't work (returned array has 0 elements), why and how do I fix it?
Is there a more elegant way, potentially avoiding the mutable CFArray?
Thanks!

You can use CFArrayCreate.
Example:
CFArrayRef NumberWrappedValuesArray(void *valueArrayPtr, size_t size, CFIndex count, CFNumberType numberType) {
size_t i, n;
CFArrayRef ret;
CFNumberRef *ref = malloc(sizeof(CFNumberRef) * count);
/* create array of boxed types. */
for (i = 0, n = count; i < n; ++i)
ref[i] = CFNumberCreate(NULL, numberType, ((char *)valueArrayPtr) + (size * i));
/* create CFArray. */
ret = CFArrayCreate(NULL, (const void **)ref, count, &kCFTypeArrayCallBacks);
/* release boxed types and malloc'ed array. */
for (i = 0; i < n; ++i)
CFRelease(ref[i]);
free(ref);
/* return CFArray, without releasing first! Has to be done by the caller. */
return ret;
}
Error handling omitted for clarity.

Related

How to write a C function to detect cycles in a void* array

I'm trying to implement the C function int contains_cycle(void *const array[], size_t length) to detect if there are any "cycles" in an array of void pointers. All elements of this array either point to an adress of this array or to NULL. Pointers still quite overwhelm me and I've got no idea where to start.
Just to clarify, what I mean by cycle, here are some examples. Just for illustration the first element's adress is always at adress 0x1 and pointers have the size of 1 byte.
{NULL, 0x3, 0x2} -> should return 1, cycle between array[1] and array [2]
{0x2, 0x3, 0x1} -> should return 1, cycle between all the elements
{0x2, 0x3, NULL} -> should return 0, no cycle
I would appreciate any help and if my goal is still not quite clear, I am happy to explain more.
My idea would be iterating over the array and somehowe "follow" the pointers to see if I end up on the starting point again. If that's the case for at least one element, I've found a cycle.
Yes. You just "follow the pointers", but you need to know whether you followed to a pointer that you already hit.
So my idea to solve your problem is to make a struct that contains an index instead of a pointer because this makes life so much easier...
typedef struct {
size_t toIndex;
bool marked;
} Entry;
Then I create a new array of all these entries with the same length as the original. I calculate the toIndex that I store in the struct using the current element's pointer minus the address of the array's beginning.
bool contains_cycle(void* array[], size_t length) {
Entry newArray[length];
for(size_t i = 0; i < length; ++i) {
size_t toIndex = ((size_t) array[i] - (size_t) &array[0] ) / sizeof *array;
newArray[i] = (Entry) { toIndex, false };
}
After that I look for the first index where the pointer is not null
size_t index = 0;
for(size_t i = 0; i < length; ++i) {
if (array[i] == NULL) continue;
index = i;
break;
}
Now, if we just let a loop run until we hit some index that is out of bounds (this will implicitly detect if we hit a NULL-element) and check if the current element is already marked. if so, return true.
while(index < length) {
if (newArray[index].marked) return true;
newArray[index].marked = true;
index = newArray[index].toIndex;
}
If the loop exits without a return you know that the loop did not start from there. You now need to check if the loop started from any other index that you haven't marked yet. But I'm too lazy to implement that now. Go try this yourself :)
For now I just return false
return false;
}
I tried to replicate your examples in the main function.
#include <stdio.h>
#include <stdbool.h>
typedef struct {
size_t toIndex;
bool marked;
} Entry;
bool contains_cycle(void* array[], size_t length) {
Entry newArray[length];
for(size_t i = 0; i < length; ++i) {
size_t toIndex = ((size_t) array[i] - (size_t) &array[0] ) / sizeof *array;
newArray[i] = (Entry) { toIndex, false };
}
size_t index = 0;
for(size_t i = 0; i < length; ++i) {
if (array[i] == NULL) continue;
index = i;
break;
}
while(index < length) {
if (newArray[index].marked) return true;
newArray[index].marked = true;
index = newArray[index].toIndex;
}
return false;
}
int main() {
void* example1[3];
void* example2[3];
void* example3[3];
example1[0] = NULL;
example1[1] = &example1[2];
example1[2] = &example1[1];
example2[0] = &example2[1];
example2[1] = &example2[2];
example2[2] = &example2[0];
example3[0] = &example3[1];
example3[1] = &example3[2];
example3[2] = NULL;
printf("%d ", contains_cycle(example1, 3));
printf("%d ", contains_cycle(example2, 3));
printf("%d ", contains_cycle(example3, 3));
}
I'm certain that there can be a faster way but the one above does work with your examples

Adding element to array, old values turns to 0 but new shows

I have written this program where I can add pics to a staff using their names. but right now it adds the new value but the already existing values becomes 0.
this is the outcome:
type in the name you would like to add pic to
Anna
type in pic
55
1.Show existing
2.add pic to a staff
1
Adam 1,2,3,
Anna 0,0,0,55,
the rest of the code:
typedef struct Staff
{
char name[30];
int *pic;
int imagecount;
} Staff;
void printStaff(Staff *pStaff)
{
printf("%s ", pStaff->name);
if ( pStaff->pic) {
for(int i=0; i<pStaff->imagecount; i++){
printf("%d,",pStaff->pic[i]);
}
}
printf("\n");
}
void PrintList(Staff aLista[], int staffCount)
{
for (int i = 0; i < staffCount; i++) {
printStaff(&aLista[i]);
}
}
UPDATED CODE:
Staff addpic(Staff array[], int staffCount)
{
Staff newStaff = {};
printf("type in the name you would like to add pic to \n");
fgets(newStaff.name, 30, stdin);
for(int i = 0; i< staffCount; i++) {
if(strcmp(array[i].name,newStaff.name)==0) {
if(array[i].imagecount<5) {
printf("type in pic\n");
int newpic;
scanf("%d",&newpic);
array[i].imagecount++;
int *newpics = realloc(newStaff.pic, (array[i].imagecount) * sizeof(int));
newpics[array[i].imagecount-1] = newpic;
array[i].pic = newpics;
}
}
}
return newStaff;
the rest of the code:
int main(void)
{
int staffCount=0;
int input;
int test[3] = {1,2,3};
Staff myStaff[5] = { {"Adam", test, 3},{"Anna",test,3} };
staffCount=2;
do
{
printf("1.Show existing \n");
printf("2.add pic to a staff");
printf("\n");
scanf("%d", &input);
switch(input)
{
case 1:
PrintList(myStaff,staffCount);
break;
case 2:
addpic(myStaff,staffCount);
break;
default:
printf("inccorect inpput\n");
break;
}
}while (input<'1' ||input<'2');
return 0;
}
any help is appreciated, but I'm new to coding so keep that in mind.
In the addpic function you do
int *newpics = realloc(array[i].pic, ...);
One problem is that if you do it for one of the two elements you have initialized in array, then array[i].pic is pointing to the first element of an array (the array test in the main function).
Arrays can not be reallocated. If you want to reallocate the memory you need to allocate the original memory dynamically as well.
newStaff.pic is initialized to NULL and not updated then, so realloc(newStaff.pic, (array[i].imagecount) * sizeof(int)); is equivalent to malloc((array[i].imagecount) * sizeof(int));.
Elements allocated via malloc() and not initialized hae indeterminate value, and they happened to be zero in this case.
You can take over the contents by manually copying them.
int *newpics = realloc(newStaff.pic, (array[i].imagecount) * sizeof(int));
/* add this line to copy contents */
for (int j = 0; j < array[i].imagecount-1; j++) newpics[j] = array[i].img[j];
newpics[array[i].imagecount-1] = newpic;
Unfortunately, this method is not good because this may cause memory leak if addition like this to the same element of array is done multiple times.
Better way is to allocate the buffer to assign to img dynamically and pass them to realloc(). Then, realloc() will do the copying for you.
Initialization part:
int test[3] = {1,2,3};
Staff myStaff[5] = { {"Adam", test, 3},{"Anna",test,3} };
staffCount=2;
/* add this to change statically allocated arrays to dynamically allocated ones */
for (int i = 0; i < staffCOunt; i++) {
int* newpics = malloc(myStaff[i].imagecount * sizeof(int));
for (int j = 0; j < myStaff[i].imagecount; j++) newpics[j] = myStaff[i].img[j];
myStaff[i].img = newpics;
}
Updating part:
/* use array[i].pic instead of newStaff.pic */
int *newpics = realloc(array[i].pic, (array[i].imagecount) * sizeof(int));
/* then, no manual copying is required */
(error checkings are omitted)

Name variables dynamically

I am creating n threads. I would like to create n variables b1,b2,b3,.,bi,..bn.
How can I do this in C? I mean to choose the name of the global variable according to the number of the thread.
thanks
Taken from NapoleonBlownapart's comment to the OP: "You can't. Variable names only exist at compile time, while threads only exist at runtime."
Use an array, with as much elements as you have threads. Then use the thread's number as index to the arrary
See some pseudo code below:
#define THREAD_MAXIMUM (42)
int b[THREAD_MAXIMUM];
thread_func(void * pv)
{
size_t i = (size_t) pv;
int bi = b[i];
...
}
int main()
{
...
for(size_t i = 0; i < THREAD_MAXIMUM; ++i)
{
b[i] = some thread specific number;
create-thread(thread_func, i) /* create thread and pass index to array element);
}
...
}
You can try with arrays or vectors(in C++). I would have preferred coding in C++ and use vector instead of C and array.
Simple implementation with array can be as follows -
#define MAX_THREAD(100)
int var[MAX_THREAD]
ThreadImpl(Params)
{
int i = (int) Params;
int vari = var[i];
}
int main()
{
for(int i = 0; i < MAX_THREAD; ++i)
{
var[i] = val; (val can be ThreadID or other value as per requirement)
pthread_create(ThreadImpl, ... other params);
}
return 0;
}

increment in a loop and keeping state

gcc 4.4.4 c89
I have the following code and 2 structures that have to be filled.
I have 3 functions that will fill the handles for each of the devices.
However, the device_type structure will need to increment from where the last function finished.
For example:
load_resources() starts at 0 and finishes at 9
dev_types starts at 0 and finishes at 9
load_networks() starts at 0 and finishes at 9
dev_types starts at 10 and finishes at 19
load_controls() starts at 0 and finishes at 9
dev_types starts at 20 and finishes at 29
However, as I don't want to use a static or global variable is there any way I can increment a
value for this. So it will start where the last function finished.
Many thanks for any suggestions,
#define NUMBER_OF_DEVICES 10
#define NUMBER_OF_TYPES 3 /* resources
networks
controls */
int events(int evt);
int load_resources();
int load_networks();
int load_controls();
static struct device_table {
int resource_handle;
int network_handle;
int control_handle;
} dev_tbl[NUMBER_OF_DEVICES];
struct device_types {
size_t id;
int dev_handle;
int dev_type;
}dev_types[NUMBER_OF_DEVICES * NUMBER_OF_TYPES];
enum dev_name_types {RESOURCE, NETWORK, CONTROL};
/* Simulates the API calls, by returning a dummy handle */
int get_resources();
int get_networks();
int get_controls();
int main(void)
{
srand(time(NULL));
load_resources();
load_networks();
load_controls();
return 0;
}
int load_resources()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].resource_handle;
dev_types[i].dev_type = RESOURCE;
}
}
int load_networks()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].network_handle = get_networks();
printf("dev_tbl[i].network_handle [ %d ]\n", dev_tbl[i].network_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].network_handle;
dev_types[i].dev_type = NETWORK;
}
}
int load_controls()
{
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
dev_tbl[i].control_handle = get_controls();
printf("dev_tbl[i].control_handle [ %d ]\n", dev_tbl[i].control_handle);
dev_types[i].id = i;
dev_types[i].dev_handle = dev_tbl[i].control_handle;
dev_types[i].dev_type = CONTROL;
}
}
Why not change the prototypes to something like:
void load_resources(int*)
(they're not actually returning anything) then, in your main code, have:
int base = 0;
load_resources (&base);
load_networks (&base);
load_controls (&base);
Each function is then responsible for using and updating *base like this:
void load_resources (int *pBase) {
size_t i = 0;
for(i = 0; i < NUMBER_OF_DEVICES; i++, (*pBase)++) { // <-- see here!
dev_tbl[i].resource_handle = get_resources();
printf("dev_tbl[i].resource_handle [ %d ]\n", dev_tbl[i].resource_handle);
dev_types[*pBase].id = i;
dev_types[*pBase].dev_handle = dev_tbl[i].resource_handle;
dev_types[*pBase].dev_type = RESOURCE;
}
}
One option is to have each of your functions take the base index as a parameter, and returning the first available index:
int index = 0;
index = load_resources(index);
index = load_network(index);
// and so on
With this yout functions would look something like this:
int load_resources(int base_index)
{
size_t i = 0;
size_t index;
for(i = 0; i < NUMBER_OF_DEVICES; i++) {
index = base_index + i;
dev_tbl[index].resource_handle = get_resources();
//
}
return index + 1;
}
By the way, your functions do have int return types, but do not return anything.
Hold a pointer or index variable within the structure itself. It's an indicator for how far the structure has been filled up generally.
There are only two ways to persist data from one scope to the next - on the stack and on the heap. Since you have already ruled out any global variables here, that would require you to use stack variables, by passing in a parameter and returning a value, or passing in a pointer to a parameter.

problem in char array?

char *funcNames[]= {"VString","VChar","VArray","VData"};
for(int i=0;i<4;i++)
{
char* temp = funcNames[i];
int len = strlen(funcNames[i]);
for(int j = 0;j<len ;j++)
{
if(j!=0)
{
char arr = temp[j];
}
}
}
here i want to separate "V" from all string in char array ...and create another char array without "V" in starting of the string.i want another char array {String,char,array,data}...i cant make a char array ....help me to solve my issue...
Do you really need a copy? You could just make a new array pointing into the original strings:
char *newArray[4];
for (i = 0; i < 4; i++) {
newArray[i] = funcNames[i] + 1;
}
If you do need to make copies then you'll have to use dynamical allocation to create the buffers to hold the copies. What you will do is declare an array of pointers and place an allocated string buffer in each of the array's entries:
char *newArray[4];
for (i = 0; i < 4; i++) {
newArray[i] = malloc(sizeof(char) * streln(funcNames[0]));
strcpy(newArray[i], funcNames[i] + 1);
}
You will have to call free() on each allocated buffer.
Or if you don't want to do allocation and are know the maximum length of the strings in funcNames:
#define MAX_FUNC_NAME_LEN 32
char newArray[4][MAX_FUNC_NAME_LEN];
for (i = 0; i < 4; i++) {
strcpy(newArray[i], funcNames[i] + 1);
}
There's only small differences between arrays and pointers so I'd opt for:
#include <stdio.h>
#include <string.h>
#include <assert.h>
int main (void) {
int i;
char *funcNames[]= {"VString","VChar","VArray","VData"};
// This is the code that dupicates your strings by allocating an array,
// then allocating each string within that array (and copying).
// Note we use strlen, not strlen+1 to mallocsince we're replacing the
// 'V' at the start with the zero byte at the end. Also we strcpy
// from char offset 1, not 0 (to skip the fist char).
char **newNames = malloc (sizeof(char*) * sizeof(funcNames) / sizeof(*funcNames));
assert (newNames != NULL);
for (i = 0; i < sizeof(funcNames) / sizeof(*funcNames); i++) {
newNames[i] = malloc (strlen (funcNames[i]));
assert (newNames[i] != NULL);
strcpy (newNames[i], funcNames[i] + 1);
}
/* Use your newNames here */
for (i = 0; i < sizeof(funcNames) / sizeof(*funcNames); i++) {
printf ("funcNames[%d] #%08x = '%s'\n", i, funcNames[i], funcNames[i]);
printf (" newNames[%d] #%08x = '%s'\n", i, newNames[i], newNames[i]);
putchar ('\n');
}
// Finished using them.
// Free the strings themselves, then free the array.
for (i = 0; i < sizeof(funcNames) / sizeof(*funcNames); i++)
free (newNames[i]);
free (newNames);
return 0;
}
You can see from the output that the locations of the variables in memory are different and that the content of the new strings is what you wanted:
funcNames[0] #00402000 = 'VString'
newNames[0] #006601c0 = 'String'
funcNames[1] #00402008 = 'VChar'
newNames[1] #006601d0 = 'Char'
funcNames[2] #0040200e = 'VArray'
newNames[2] #006601e0 = 'Array'
funcNames[3] #00402015 = 'VData'
newNames[3] #006601f0 = 'Data'

Resources