How do I return null if my string has no null terminator
this is my first time posting here so sorry if I'm doing something wrong.
I have a C programme that allocates a pool, then stores a char array, "Hello World", in memory and then retrieves it. One of the lines of the code in my main method reads:
store(pool, 50, sizeof(str) - 1, str);
(my store method variables are (Pool *pool, int offset, int size, void *object)
If I am reading this correctly, then the pool being allocated is 1 less than the string size, so cutting of the that would be on the end.
How do I check that character is missing off the end and return null because of it?
/* _POOL - pool
* int size - the size of the pool in bytes
* void* ipPool - pointer to memory malloc'd by the operating system
*/
typedef struct _POOL
{
int size;
void* memory;
} Pool;
/* Allocate a memory pool of size n bytes from system memory (i.e., via malloc())
* and return a pointer to the filled data Pool structure */
Pool* allocatePool(int n)
{
if(n <= 0)
{
return NULL;
}
Pool *pool = malloc(sizeof *pool);
if(!pool)
{
return NULL;
}
pool->size = n;
if(!(pool->memory = malloc(n)))
{
return NULL;
}
return pool;
};
/* Free a memory pool allocated through allocatePool(int) */
void freePool(Pool *pool)
{
if(!pool)
{
return;
}
if(pool->memory)
{
free(pool->memory);
}
free(pool);
};
/* Store an arbitrary object of size n bytes at
* location offset within the pool */
void store(Pool *pool, int offset, int size, void *object)
{
if(!pool)
{
return;
}
if(size + offset > pool->size)
{
return;
}
memcpy(pool + offset, object, size);
};
/* Retrieve an arbitrary object of size n bytes
* from a location offset within the pool */
void *retrieve(Pool *pool, int offset, int size)
{
if(!pool)
{
return NULL;
}
void *obj = malloc(size);
if(!obj)
{
return NULL;
}
if(size + offset > pool->size)
{
return NULL;
}
return memcpy(obj, pool + offset, size);
};
void main()
{
const int poolSize = 500;
Pool* pool;
int x = 5;
char c = 'c';
char str[] = "Hello World";
/* Should retrieve Hello World */
store(pool, 8, sizeof(str), str);
printf("Test 4: Store an arbitrary multi-byte valuen");
printf("tStored: %sn", str);
printf("tRetrieves: %sn", (char*)retrieve(pool, 8, sizeof(str)));
/* Should retrieve null */
store(pool, 50, sizeof(str) - 1, str);
printf("Test 5: Store an arbitrary multi-byte value with no null terminatorn");
printf("tStored: %sn", str);
printf("tRetrieves: %sn", (char*)retrieve(pool, 50, sizeof(str) - 1));
};
is all the code that I think is involved. This is currently putting in Hello World and retrieving Hello World.
I cannot edit any of the main method, only the contents of the functions and the struct.
If you removed the trailing null character, you erased the only info that encoded the string´s length. There is no way to query the size of the block allocated.
This is because the terminating zero is C´s way of encoding the string length. Other languages´ runtimes use different methods, like storing the string length (as a byte, or word) in the very first byte pointed to by the string-referencing variable (Delphi for example).
So there is no way to detect if the trailing null is missing or not. If it is there, you can search for it. If it is not there, your search will inevitably access memory locations behind the last byte of the string, and fail to work correctly.
And because this search (or scan) for the null character is exactly what strlen
is doing, you cannot use strlen
, of course.
This shows how to test if there is a string terminator.
In the first case str
is automatically sized and the '