Copy Data to a pointer in C - c

I have a pointer
uint8_t *dataPtr
and I want to loop incrementing the pointer by one, copying bytes in one by one as they arrive from hardware.
My issue is how to copy data into the memory location of that pointer. Sounds so simple but I'm at a loss.
E.g.
uint8_t *dataPtr = (uint8_t*) data;
uint8_t tempData = 0;
for (uint8_t byteCnt = 0; byteCnt < noOfDataBytes; byteCnt++)
{
// TODO: Get tempData
dataPtr = tempData; // How to copy tempData into the location of dataPtr.
dataPtr++;
}

Thanks everyone.
Looks so obvious now and I had already tried *dataPtr before posting. I had another issue that prevented that working before which caused the confusion.
What's wrong with the type
for (uint8_t byteCnt = 0; ...

Related

ERROR "realloc(): invalid next size" when allocating memory to const char*** variable

I have a function
populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter)
which take a pointer to an array of strings and the number of elements in the array as parameters.
I allocate initial memory to that array using malloc(0). Specs say that it will either return a null pointer or a unique pointer that can be passed to free().
int currentAvailableExtensionCount = gCounter;
This variable will store number of string in gAvailableExtensions.
Inside this for loop
for (int i = 0; i < availableExtensionCount; ++i)
I have this piece of code
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].name);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
where
availableExtensionProperties[i].name
returns a string.
This is how that struct is defined
typedef struct Stuff {
char name[MAX_POSSIBLE_NAME];
...
...
} Stuff;
realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
should add memory of size sizeOfAvailableExtensionName to *gAvailableExtensions de-referenced array.
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
&availableExtensionProperties[i].name,
sizeOfAvailableExtensionName);
should copy the string (this sizeOfAvailableExtensionName much memory) from
&availableExtensionPropterties[i].name
address to
&(*gAvailableExtensions)[currentAvailableExtensionCount]
address.
But I don't think the code does what I think it should because I'm getting this error
realloc(): invalid next size
Aborted
(core dumped) ./Executable
EDIT: Full code
uint32_t populateAvailableExtensions(const char** gAvailableExtensions[], int gCounter) {
int currentAvailableExtensionCount = gCounter;
void* reallocStatus;
uint32_t availableExtensionCount = 0;
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, VK_NULL_HANDLE);
VkExtensionProperties availableExtensionProperties[availableExtensionCount];
vkEnumerateInstanceExtensionProperties(
VK_NULL_HANDLE, &availableExtensionCount, availableExtensionProperties);
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
return currentAvailableExtensionCount;
}
This is how an external function calls on that one,
uint32_t availableExtensionCount = 0;
availableExtensions = malloc(0);
availableExtensionCount = populateAvailableExtensions(&availableExtensions);
and
const char** availableExtensions;
is declared in header file.
EDIT 2: Updated the code, now gCounter holds the number of elements in gAvailableExtensions
This loop is totally messy:
for (int i = 0; i < availableExtensionCount; ++i) {
size_t sizeOfAvailableExtensionName =
sizeof(availableExtensionProperties[i].extensionName);
reallocStatus = realloc(*gAvailableExtensions, sizeOfAvailableExtensionName);
memcpy(&(*gAvailableExtensions)[currentAvailableExtensionCount],
availableExtensionProperties[i].extensionName,
sizeOfAvailableExtensionName);
++currentAvailableExtensionCount;
}
I assume the only lines that does what you expect them to do, are the lines for (int i = 0; i < availableExtensionCount; ++i) and ++currentAvailableExtensionCount;
First, the typical way to use realloc is like this:
foo *new_p = realloc(p, new_size);
if (!new_p)
handle_error();
else
p = new_p;
The point is that realloc will not update the value of p if a reallocation happens. It is your duty to update 'p'. In your case you never update *gAvailableExtensions. I also suspect that you don't calculate sizeOfAvailableExtensionCount correctly. The operator sizeof always return a compile time constant, so the realloc doesn't actuall make any sense.
The memcpy doesn't actally make any sense either, since you are copying the string into the memory of a pointer array (probably with an additional buffer overflow).
You said that *gAvailableExtensions is a pointer to an array of pointers to strings.
That means that you have to realloc the buffer to hold the correct number of pointers, and malloc memory for each string you want to store.
For this example, I assume that .extensionName is of type char * or char[XXX]:
// Calculate new size of pointer array
// TODO: Check for overflow
size_t new_array_size =
(currentAvailableExtensionCount + availableExtensionCount) * sizeof(*gAvailableExtensions);
char **tmp_ptr = realloc(*gAvailableExtensions, new_array_size);
if (!tmp_ptr)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
*gAvailableExtensions = tmp_ptr;
// Add strings to array
for (int i = 0; i < availableExtensionCount; ++i)
{
size_t length = strlen(availableExtensionProperties[i].extensionName);
// Allocate space for new string
char *new_s = malloc(length + 1);
if (!new_s)
{
//TODO: Handle error;
return currentAvailableExtensionCount;
}
// Copy string
memcpy (new_s, availableExtensionProperties[i].extensionName, length + 1);
// Insert string in array
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
++currentAvailableExtensionCount;
}
If you can guarantee that the lifetime of availableExtensionProperties[i].extensionName is longer than *gAvailableExtensions, you can simplify this a little bit by dropping malloc and memcpy in the loop, and do:
char *new_s = availableExtensionProperties[i].extensionName;
(*gAvailableExtensions)[currentAvailableExtensionCount] = new_s;
Some harsh words at the end: It seems like you have the "Infinite number of Monkeys" approach to programming, just hitting the keyboard until it works.
Such programs will just only give the illusion of working. They will break in spectacular ways sooner or later.
Programming is not a guessing game. You have to understand every piece of code you write before you move to the next one.
int currentAvailableExtensionCount =
sizeof(*gAvailableExtensions) / sizeof(**gAvailableExtensions) - 1;
is just a obfuscated way of saying
int currentAvailableExtensionCount = 0;
I stopped reading after that, because i assume that is not what you intend to write.
Pointers in c doesn't know how many elements there are in the sequence they are pointing at. They only know the size of a single element.
In your case *gAvailableExtensions is of type of char ** and **gAvailableExtensions is of type char *. Both are pointers and have the same size on a typical desktop system. So on a 64 bit desktop system the expression turns into
8/8 - 1, which equals zero.
Unless you fix this bug, or clarify that you actually want the value to always be zero, the rest of the code does not make any sense.

Pointer as index value in for loop

I'd like to use a few for loops in C and use common index for these. I want to use pointer, because I will be able to free it later.
I thought about something like:
uint8_t *p = malloc(sizeof(uint8_t));
for (*p = 0; *p < 255; *p++)
{
// Instructions...
}
// A few loops...
free(p);
But this code doesn't work as I want. How can I fix it?
PS I'm a beginner in C's pointers.
By this line:
uint8_t *p = malloc(sizeof(uint8_t));
You're allocating memory that is suitable to hold ONE uint8_t. You shouldn't touch any other addresses after p because you didn't allocate them. You may need to do the following:
uint8_t *p = malloc(255 * sizeof(uint8_t));
The previous line allocates memory that can hold 255 uint8_t instead of just one. That way, you can access addresses from p to p + 254.
OK, I solved the problem. My code:
uint8_t *p = malloc(sizeof(uint8_t));
for (*p = 0; *p < 255; (*p)++)
{
// Instructions...
}
// A few loops...
free(p);
Thank you all for your answers!
Syntax of malloc is :
int * p = (*int )malloc(sizeof(int);
You have to first convert the data type into pointer

Writing to array of pointers in C

I need to write the pointer address of a struct (struct is called "Post") that has reposted another Post. There's a fixed return type called result with the following declaration:
struct result {
void** elements;
size_t n_elements;
};
For the Post struct, it has the following declaration:
struct post {
uint64_t pst_id;
uint64_t timestamp;
size_t* reposted_idxs;
size_t n_reposted;
};
Here's my code:
result* find_all_reposts(post* posts, size_t count, uint64_t post_id, query_helper* helper) {
result * ret_result = (result *) malloc(sizeof(result));
ret_result->elements[100];
ret_result->n_elements = 0;
for(int i = 0; i < count; i++){
post * temp = &posts[i];
size_t total_reposted = temp->n_reposted;
if(total_reposted > 0){
for(int q = 0; q < total_reposted; q++){
int index_of_repost = temp->reposted_idxs[q];
ret_result->elements[q] = &posts[index_of_repost];
ret_result->n_elements++;
}
}
}
return ret_result;
}
However I get a SEGV error for ret_result->elements[q] = &posts[index_of_repost];. I thought it could be originally that I hadn't initialised the elements field in the ret_result struct but I receive warning: statement with no effect for that:
warning: statement with no effect [-Wunused-value]- ret_result->elements[100];
I'm thinking that the void ** type for the elements field in result might be messing me around. From what I understand that's a pointer to a pointer which can obviously be an array and hence is basically a pointer to an array of posts?
I should clarify that count is the number of posts and that the returned-result is managed separately and hence any heap-allocated memory is freed in a separate process.
Thanks for your help :)
You haven't initialized ret_result->elements to anything. The statement ret_result->elements[100] is a no-op, the only reason you're not segfaulting there too is because your compiler is cutting it out. If you want that field to be a pointer to an array of size 100 you must initialize it with malloc. I'm not sure why you're declaring it to be a void ** double pointer here, but if it must be that way then something like this might work:
ret_result->elements = malloc(100 * sizeof(struct post *));
The call's arguments could also be 100 * sizeof(void *), but it might be a little what you intend to store there if you specify the struct to which the data will be pointing.

Realloc doesn't seem to enlarge array

so I have to write something like garbage collector for school project in C. I am stuck at problem with dynamic memory allocation. My function growActivePtrs() should enlarge global array of structs by one, but it does not seem to be working. I have read a ton on materials on dynamic allocation and tried many things, but I just cant find the mistake.
typedef struct activePtr
{
// pointer to actively used memory
void *memPointer;
// number of times this memory is referenced
int timesUsed;
} activePtr;
activePtr **activePointers;
size_t *ptrCount = 0;
bool growActivePtrs()
{
const size_t totalSize = *ptrCount + 1;
activePtr *temp = (activePtr *)realloc(*activePointers, (totalSize * sizeof(activePtr)));
if (temp == NULL) {
return false;
}
*activePointers = temp;
*ptrCount += 1;
activePointers[*ptrCount - 1]->timesUsed = 0;
activePointers[*ptrCount - 1]->memPointer = NULL;
return true;
}
Any help will be much appreciated. Thank you.
size_t *ptrCount = 0;
This defines ptrCount as a pointer to size_t, initialised to a null pointer. Unless you assign it the location of some actual size_t object (and it looks like you haven't), any attempt to access *ptrCount is doomed to fail.
There is no reason why this should be a pointer. You can just store a size_t directly.
As #user3121023 rightly points out in a comment, the same applies to your activePointers variable.

C - How can I save structs to a malloc'd section of memory?

My question's pretty basic, but it's been a while. I'm reading in a text file and saving numbers in the text to a struct 'Record'. After I read text to my Record buffer, I want to place it in an area of memory.
typedef struct
{
int line_status[64];
float line_data[64], relativetime;
unsigned long blkhdr_ticks;
} Record;
Record *storage;
storage = (Record*)malloc(nRange*sizeof(Record));
Record buffer;
Where nRange is some random number, and buffer is a Record with values, though I haven't listed my code that assigns these to the buffer. I thought the syntax was something like:
&storage = buffer;
But I know that's not right. Any help would be greatly appreciated.
You can also treat storage as an array.
storage[0] = buffer;
storage[1] = anotherBuffer;
...
storage[nRange-1] = lastBuffer;
You should be able to say *storage = buffer; or storage[0] = buffer;.
Since storage can also be regarded as an array of nRange records (I guess that really is your intention) you can simply do:
storage[0] = buffer;
storage[someOtherIndex] = buffer;

Resources