Pointer of substring from pointer of string - c

I'm quite new to C and struggle with the following.
Consider a string (pointer to an array of characters), containing an arbitrary amount of unsigned bytes, in our case, let it be programming. Write a function, which returns a pointer to a new location in memory (but not allocated with malloc), containing the substring of arbitrary but fixed size, at an arbitrary offset - in our case, let it be gramm.
I tried with the following:
unsigned char* newptr(unsigned char* p, int offset, int size) {
unsigned char r[size];
memcpy(r, p + offset, size + 1);
return r;
}
but it errors with Segmentation fault. Otherwise
unsigned char* newptr = oldptr + offset;
works but it doesn't solve the problem with the fixed size - I don't want the rest of chars belonging to the pointer.
Thanks in advance and sorry if the question was asked before, I just couldn't find anything of help.

Some possible solutions, all them are non-optimal:
Using global buffer (using global variable is bad practice and if you call the function again it rewrites the buffer, buffer has fixed size and it must be larger then your size):
unsigned char r[100000];
unsigned char* newptr(unsigned char* p, int offset, int size) {
memcpy(r, p + offset, size);
r[size] = '\0';
return r;
}
Using static local buffer (has mostly the same problems as solution with global buffer):
unsigned char* newptr(unsigned char* p, int offset, int size) {
static unsigned char r[100000];
memcpy(r, p + offset, size);
r[size] = '\0';
return r;
}
Using memory of input variable as buffer (the problem is then *p changes after the function call)
unsigned char* newptr(unsigned char* p, int offset, int size) {
p[offset + size] = '\0';
return p + offset;
}
Passing allocated buffer into function:
unsigned char* newptr(unsigned char* p, int offset, int size, unsigned int* r) {
memcpy(r, p + offset, size);
r[size] = '\0';
return r;
}

Related

Understanding code of function strlen in C Programming

I was given a solution to the problem of recreating the function strlen in C Programming and it was the following, I need help understanding what the code is actually doing.
void *ft_memset(void *b, int c, size_t len)
{
size_t i;
i = 0;
while (i < len)
{
((unsigned char *)b)[i] = c;
i++;
}
return (b);
}
My biggest doubts are the meaning of ((unsigned char *)b)[i] = c, specially because I don't understand the ( *)b, and the need for a return b in a void function.
Thank you very much for your help, sorry if I did something wrong its my first post in stack overflow.
Let's break it down, albeit my C skills are somewhat rusty. Edits are welcome :)
void *ft_memset(void *b, int c, size_t len)
{
size_t i;
i = 0;
while (i < len)
{
((unsigned char *)b)[i] = c;
i++;
}
return (b);
}
First, you have declared a function called ft_memset which returns void *.
void * means a pointer to any object. It's just a number, pointing to a memory address. But we do not know what's in it because it's not properly annotated.
Your function takes three arguments:
b which is a pointer to anything (or void pointer if you will)
c which is an int 32-bit signed integer number.
len which is a size_t which is usually an alias to an unsigned integer. Read more about size_t over here
Your function iterates through the first len bytes and sets the c's value to those.
We're basically overwriting b's contents for the first len bytes.
Now, what does ((unsigned char*)b) mean. This statement is casting your void * to an unsigned char* (byte pointer), this is just
telling the compiler that we're gonna deal with the contents pointed by b as if they were just a unsigned char.
Later we're just indexing on the i-th position and setting the value c in it.
Understanding code of function strlen
void *ft_memset(void *b, int c, size_t len) is like void *memset(void *s, int c, size_t n). They both assign values to the memory pointed to by b. These functions are quite different form strlen().
size_t strlen(const char *s) does not alter the memory pointed to by s. It iterates through that memory looking for a null character.
size_t strlen(const char *s) {
const char *end = s;
while (*end != '\0') {
end++;
}
return (size_t)(end - s);
}
// or
size_t strlen(const char *s) {
size_t i = 0;
while (s[i] != '\0') {
i++;
}
return i;
}

What is the best way to copy a buffer and return a pointer to the next available element?

I have developed a function for copying elements from one unsigned char buffer to another. I designed the function to return a pointer to the next available (empty) element in the destination buffer. The point of doing that is so that I know where start writing to the destination buffer if I choose to call the function again and write more data to the destination buffer (from some other source buffer). Here is the function:
unsigned char *copyBuffer(unsigned char *sourceBuf,
unsigned char *destBuf,
int size)
{
int i = 0;
for (i; i < size; ++i) {
*(destBuf + i) = *(sourceBuf + i);
};
// return a pointer to the next unpopulated element in the dest buffer
return (destBuf + i + 1);
}
The dilemma I have is that though this compiles fine, I think I may run into runtime issues because I may be referencing an out-of-bounds pointer once the destination buffer has been completely filled.
For example:
unsigned char destBuf[10];
unsigned char sourceBuf1[6];
unsigned char sourceBuf2[4];
unsigned char *pBuffer = NULL;
pBuffer = copyBuffer(sourceBuf1, destBuf, 6);
copyBuffer(sourceBuf2, pBuffer, 4);
After the second copy operation, won't the pointer returned be out of bounds because the last line of my function is
return (destBuf + i + 1);
How can I achieve the functionality that I'm seeking without having this issue? Or is there another way entirely to achieve this which is better?
Thanks in advance.
Add additional parameter showing the size of the buffer. Return value NULL indicates that the buffer is full.
destBuf + i + 1 does not point to the next "free" character, only one after
use the correct type for size.
unsigned char* copyBuffer(const unsigned char *sourceBuf, unsigned char *destBuf, const size_t size, const size_t destbuffsize)
{
char *result = NULL;
memcpy(destBuf, sourceBuf, size <= destbuffsize ? size : destbuffsize);
if(size < destbuffsize) result = destBuf + size;
return result;
}
There is a problem in your approach: while it is OK to return a pointer one past the address of the last element of an array, you actually return a pointer 1 byte beyond the end. Is this the intent? i is incremented after the last copy so buf + i points to the next available element.
Note also these remarks:
sourceBuf should be declared as const unsigned char * as you do not modify the source buffer.
the ; after the body of the for loop is redundant, remove it.
the lonely i in the first clause of the for is useless and confusing.
I would suggest using size_t for the type of size and i
the order of arguments is confusing as it is the opposite of that of memcpy.
Here is a modified version:
unsigned char *copyBuffer(unsigned char *destBuf,
const unsigned char *sourceBuf,
size_t size)
{
size_t i;
for (i = 0; i < size; ++i) {
destBuf[i] = sourceBuf[i];
}
// return a pointer to the next unpopulated element in the dest buffer
return destBuf + i;
}
Incrementing the pointers allows for a simpler version:
unsigned char *copyBuffer(unsigned char *destBuf,
const unsigned char *sourceBuf,
size_t size)
{
while (size --> 0) {
*destBuf++ = *sourceBuf++;
}
// return a pointer to the next unpopulated element in the dest buffer
return destBuf;
}
This above function has the same behavior as mempcpy() available in the GNU libC and some other ones:
void *mempcpy(void *dest, const void *src, size_t n);
You should consider using this one as it is optimized on systems that support it and can be easily added on systems lacking it.

Use realloc() after malloc() to change the size of unsigned char array

In the main function, I use malloc() to create an unsigned char array:
int main()
{
int length = 64;
unsigned char *array = (unsigned char *)malloc(length * sizeof(unsigned char));
...
change_size(array, length);
}
change_size() defined in .h:
void change_size(unsigned char* arr, int len);
In the change_size function, I will use realloc() to increase the array size:
void change size(unsigned char* arr, int len)
{
printf("%d\n", len);
len = len + 16;
printf("%d\n", len);
arr = (unsigned char *)realloc(arr, len * sizeof(unsigned char));
int new_len = sizeof(arr)/sizeof(arr[0]);
printf("%d\n", new_len);
}
The printf() show me:
64
80
8
The array size in the main() also needs to be updated.
Then how to change this array size correctly?
You need to pass your parameters as pointers if you want to change their value back in the caller. That also means you pass your array pointer as a pointer, because realloc might change it:
int change_size(unsigned char **arr, int *len)
{
int new_len = *len + 16;
unsigned char *new_arr = realloc(*arr, new_len);
if (new_arr) {
*len = new_len;
*arr = new_arr;
}
return new_arr != NULL;
}
Here I've modified change_size to suit, and also added a return value to indicate success, since realloc can fail to resize the memory. For clarity, I removed the printf calls. Oh, and I also removed the cast, since that is not valid in C.
Example usage:
if (!change_size(&array, &len))
{
perror("change_size failed");
}
One final note is that you can use your change_size function for the first allocation too, rather than calling malloc. If the first argument to realloc is NULL, it does the same thing as malloc.
First C is not babysitter language,
You only need basic things then you can do everything,
Just try hard to totally understand basic.
#include <stdio.h>
#include <stdlib.h>
int main(){
int G1_Len=20;
int G2_Len=40;
char* G1=(char*)malloc(sizeof(char)*G1_Len);
char* G2=(char*)malloc(sizeof(char)*G2_Len);
printf("This is G1's Size:%d,Becuz G1 is Pointer\n",sizeof(G1));
printf("%d\n",sizeof(G2));
printf("This is what you need just add a variable remainber your size\n%d\n",G1_Len);
printf("%d\n",G2_Len);
/*alloc and free is a pair of memory control you need,remember least function thinking more is tip of C*/
/*if you need alot of function but you cant control all try c++*/
/*and if in c++ using new and delete dont use malloc free*/
free(G1);
free(G2);
G1=NULL;
G2=NULL;
G1_Len=22;
G1=(char*)malloc(sizeof(char)*G1_Len);
//Now you have 22 bytes of char array
free(G1);
return 0;
}
Okay I answer it. #Chipster
#include <stdio.h>
#include <stdlib.h>
int change_size(char** arr, int len)
{
char* nar=(char*)malloc(sizeof(char)*(len+16));
if(nar){
free(* arr);
*arr=nar;
nar[10]='K';//this will let you know its right
return len+16;
}
return len;
}
int main(){
int G1_Len=20;
int G2_Len=40;
char* G1=(char*)malloc(sizeof(char)*G1_Len);
char* G2=(char*)malloc(sizeof(char)*G2_Len);
printf("This is G1's Size:%d,Becuz G1 is Pointer\n",sizeof(G1));
printf("%d\n",sizeof(G2));
printf("This is what you need just add a variable remainber your size\n%d\n",G1_Len);
printf("%d\n",G2_Len);
/*alloc and free is a pair of memory control you need,remember least function thinking more is tip of C*/
/*if you need alot of function but you cant control all try c++*/
/*and if in c++ using new and delete dont use malloc free*/
free(G1);
free(G2);
G1=NULL;
G2=NULL;
G1_Len=22;
G1=(char*)malloc(sizeof(char)*G1_Len);
//Now you have 22 bytes of char array
printf("%d\n",G1);
G1_Len=change_size(&G1,G1_Len);
printf("%c\n",G1[10]);
printf("%d\n",G1);
printf("%d\n",G1_Len);
free(G1);
return 0;
}

Save a block of data from memory to byte array to restore later the block from byte array

I have the following code:
typedef struct {
struct {
uint64_t key;
uint64_t hash;
uint64_t size;
uint64_t body;
} length;
} block_head;
-----------------------------------------------------
//Block allocation
uint64_t d1, d2, d4; //Lengths for octet strings to be saved in memory block
uint64_t d3; //just for saving a size - integer value
unsigned char **data = (unsigned char**)malloc(sizeof(block_head) + d1 + d2 + d4);
block_head *head = (block_head *)data;
head->length.key = d1;
head->length.hash = d2;
head->length.size = d3;
head->length.body = d4;
-----------------------------------------------------
//Later we fill memory of data block
// get a pointer key buffer location
unsigned char *d = (char *)data + sizeof(secure_head_t);
//Add octet string
FillData1(d);
// get a pointer to the body buffer location
unsigned char *body = (unsigned char *)data + (sizeof(block_head) + head->length.d1 + head->length.d2);
//get the length of the body free space (of a block)
int body_length = head->length.body;
//body is filled with octet string, and length is saved to body_length
FillBody2((unsigned char*)body, &body_length)
// Advance the body pointer to the location of the remaining space, and calculate just how much room is still available.
body += body_length;
// Save another octet string to block
FillBody3((unsigned char *)data + (sizeof(block_head) + head->length.key), &body_length);
Now I need to save the filled block (unsigned char **data) to a byte array, to restore later from array to a block.
I do this but it is not working:
unsigned char **data = some_filled_data;
block_head *head = (block_head *)data;
// convert data to arr
unsigned char *arr = (unsigned char *)malloc( sizeof(block_head) + (head->length.key + head->length.hash + head->length.body));
memcpy(&arr, data, sizeof(block_head) + (head->length.key + head->length.hash + head->length.body));
// convert arr to data
unsigned char *data = (unsigned char*)malloc( sizeof(unsigned char) * strlen(arr));
memcpy(&data, &arr, strlen(arr));
If I try to use the new converted block from arr, then I will get an error, because it is not constructed correctly or something like this
How I should convert correctly data to arr and arr to data, to represent the same block ?
While I could not decipher the description, this answers the title:
typedef struct {
int a;
char b[20];
} Test;
void fillAndBackupTest(char **out) {
Test test;
test.a = 20;
strcpy(test.b, "Hello!");
*out = (char*) malloc(sizeof Test);
memcpy(*out, &test, sizeof Test);
}
void restoreAndPrintTest(char *in) {
Test test;
memcpy(&test, in, sizeof Test);
printf("a: %d, b: %s\n", test.a, test.b);
}
int main()
{
char *blob;
fillAndBackupTest(&blob);
restoreAndPrintTest(blob);
free(blob);
return 0;
}
A structure type, Test is defined, fillAndBackupTest() creates one, fills its fields and stores a "copy" of it into a buffer it allocates for itself (it is a char* for now, but actually it could very well remain being void*), then restoreAndPrintTest() restores a (different) Test instance from this buffer and prints its contents.
What you do with malloc-ing a sum of a size and some arbitrary numbers (key? body?) does not seem to be a good idea, and strlen can not measure the length of a binary blob either.

Understanding the StrBuff In C

I need to know if this StrBuff struct is supposed to operate like an array. I've looked and looked, and honestly can't tell just due to the pointer syntax - it seems like as an array it could work, and as an array it could not work.
I see that in the second method, malloc() is used, so I'm guessing that the buf-str uChar is supposed to be an array.
Teh codez:
typedef struct {
unsigned char *str;
unsigned int len;
} StrBuf;
static StrBuf *
strbuf_new ()
{
StrBuf *buf;
buf = (StrBuf *) calloc (sizeof (StrBuf), 1);
buf->str = (unsigned char *) strdup ("");
return buf;
}
static void
strbuf_append (StrBuf *buf, unsigned char *data, int len)
{
int offset;
if (len <= -1)
len = strlen ((char *) data);
offset = buf->len;
buf->len += len;
buf->str = (unsigned char *) realloc (buf->str, buf->len + 1);
memcpy (buf->str + offset, data, len);
buf->str[buf->len] = '\0';
}
So, judging from these methods I'm guessing for any C/C++ veterans out there this should be a piece of cake.
Edit:
My goal has been to convert an app (which uses this code here) into a Java port, but I've been quite confused as to how I should do it. I've gotten fairly far doing (for the most part) the same thing in Java, only this time using a byte[] array, seeing as how unsigned chars are supposed to be equivalent to bytes in Java.
It's not an array. It's a structure to hold values (probably strings) using dymamic memory allocation. If you use an array to allocate some datas, then array size is determined at compile time.
For example:
char buf[10];
With a structure like StrBuf you can allocate the required memory when the string buf of the given length is supplied :
buf->str = (unsigned char *) realloc (buf->str, buf->len + 1);

Resources