Getting 'Segmentation Fault' when running simple string manipulation program - c

I'm trying to learn some C and am having a little bit of trouble with manipulating strings. In trying to learn them, I've decided to make a simple spanish verb conjugator, but I'm getting stuck. Right now I'm just trying to drop the last 2 non '\0' of the string and then add a 'o' to it. (For example, for an input of "hablar" I want it to output "hablo"). Here's my code. I've tried to be overly detailed in my comments to hopefully aid in figuring out what I'm missing conceptually.
#include <stdio.h>
#include <string.h>
/* Reimplemented the length function of a string for practice */
int len(char *);
void conjugatePresentAr(char *, char *);
int len(char *arr){
int l = 0;
while (*arr++ != '\0'){
l++;
}
return l;
}
void conjugatePresentAr(char *verb, char *output){
output = verb;
int i = len(verb);
while (output < (verb + i -2)){
*output = *verb;
output++;
verb++;
}
*output = 'o';
output++;
*output = '\0';
}
int main(){
char input[20];
scanf("%s", input);
printf("%s\n",input);
char conjugated[20];
conjugatePresentAr(input, conjugated);
printf("%s\n", conjugated);
return 0;
}
For any input I get Segmentation Fault: 11. I've spent a decent amount of time looking around here and reading through books on pointers but can't quite seem to figure out what I'm messing up. I appreciate your help!

In conjugatePresentAr() you have changed the argument *output, possibly because you thought that copies the string.
output = verb;
so the function doesn't write anything to the string you supplied. Then when you print it, it's still an uninitialised variable.

int i = len(verb);
while (output < (verb + i -2)){
*output = *verb;
output++;
verb++;
}
will keep going forever: you're chasing (verb + i - 2) as it recedes into the distance (you increment verb inside the loop).
Try something like:
char *end = verb + strlen(verb) - 2;
while (output < end) {
...
verb++; /* this doesn't change end */
}
(and also fix the bug Weather Vane spotted which I entirely missed).
Note: in general, string processing is hard to do well in C, because the built-in facilities are so low-level. It's actually much easier to use C++ with its string and stringstream facilities.
If you're sticking to C, explicitly tracking length and allocated capacity alongside the char pointer (as the C++ string does for you) is good practice. Oh, and there's no obvious benefit to re-writing strlen.

You can't copy strings (char *) by assignment, like you did here:
output = verb;
What you do here is just change output to point at the input string, so any changes made to one of the strings will also apply to the other one - since they both point to the same memory.
you need to explicitly a function for copying the memory - such as strcpy (make sure to supply a null terminated string) or memcpy.
And, regarding your logic, since you don't really check the string for 'ar' in the end, and just assume there is, why not use something a little simpler like this:
void conjugatePresentAr(char *verb, char *output)
{
strcpy(output,verb);
int len = strlen(verb);
output[len - 2] = 'o';
output[len - 1] = '\0';
}

In function conjugatePresentAr() you have alterered the argument *output
output = verb;
Is an address affectation, not value.
Should reread pointer definition

Related

How to dynamically allocate string using void function?

First of all Thanks for visiting my question... :)
I am interested in competitive programming, so I daily do some amount of problem-solving, however, I only know C language at a decent level, and I often face problems while dynamically allocating something as usual, especially for strings and 2D arrays.
But I somehow manage to find ways (thanks to StackOverflow), for example, I wanted to create a function that scans string dynamically until the user enters space or new line, so I came up with the solution below and it works perfectly:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// scanf("%[^\n]%*c", str);
char *create_string(char *ptr)
{
ptr = (char *)malloc(0 * sizeof(char));
unsigned int size = 0;
char c = 0;
while (1)
{
scanf("%c", &c);
if (c == 32 || c == 10)
{
break;
}
size++;
ptr = (char *)realloc(ptr, size * sizeof(char));
ptr[size - 1] = c;
}
ptr = (char *)realloc(ptr, (size + 1) * sizeof(char));
ptr[size] = '\0';
return ptr;
}
int main()
{
char *str;
str = create_string(str);
printf("%s", str);
printf("\n%lu", strlen(str));
return 0;
}
And now for curiosity purposes, I want to know how can I do this same thing using the void function?, something like:
char *str;
create_string(&str);
should start storing everything in the dynamic memory which is pointed by str.
Also, please if you have more knowledge to show in DMA for 2D array, then please show me it, feel free to give examples with different problems.
And also How can I stop scanning the string (which was allocated dynamically) with specific string ending? for example, scanning(any kind of scanning, i.e. int, bool, custom structures etc...) should stop if user enters string "STOP", Please feel free to give pictorial examples.
Because I am sure that this question is burning like a fire in beginner's and intermediate C programmers' minds.
As C passes arguments by value, to return something via an out parameter, you need to pass in a pointer to it. So to return a char * it would:
void create_string(char **s) {
*s = malloc(42);
}
Here is your refactored code. I changed the following:
Eliminate return value of update caller.
Initialize *ptr = malloc(1) for the trailing '\0'. It eliminates an unnecessary and implementation defined malloc(0). This also eliminates the (*ptr)[size] = ... which looks wrong as the last index is expected to be size - 1. Alternatively initialize it to NULL.
Use character constants instead of magic values (32, 10).
sizeof(char) is defined as 1 so leave it out.
Reduced scope of variable c.
free() memory allocated.
(cosmetic) Use size_t size instead of unsigned int size.
(cosmetic) Avoid the noise of casting casting void *.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void create_string(char **ptr) {
*ptr = malloc(1);
size_t size = 1;
for(;;) {
char c;
scanf("%c", &c);
if (c == ' ' || c == '\n') break;
(*ptr)[size-1] = c;
size++;
*ptr = realloc(*ptr, size);
}
(*ptr)[size-1] = '\0';
}
int main() {
char *str;
create_string(&str);
printf("%s\n", str);
printf("%zu\n", strlen(str));
free(str);
}
I didn't fix these issue:
Check return value of malloc(), realloc().
v = realloc(v, ...) is unsafe and will leak memory if realloc() fails. You need to do char *tmp = realloc(v,...); if(!tmp) { // err }; v = tmp;.
Check return value of scanf() otherwise you may be operating on uninitialized data.
Use scanf("%s", ..) instead of for(;;) { scanf("%c", ...). It's more efficient to allocate a chunk at a time instead of per byte.
If user enters ctrl-d (EOF) the program will go into an infinite loop.
It's good idea to separate i/o from logic (i.e. let caller do the scanf(). That way create_string() is much more reusable.

Cause of seg fault in C

In my program I am getting a seg fault and I'm not sure the cause or how to find out the cause. Any help would be greatly appreciated!
In the code I am trying to read word by word, but I need to keep track of the line numbers. Then I am trying to create a linked list where the data is the word and line number.
(there are two files compiled together)
void main(int argc, char **argv){
file = fopen(argv[1],"r");
struct fileIndex *fIndex = NULL;
delimiters = " .,;:!-";/*strtok chars to seperate*/
int wCount = wordcount(file);/*number of words in file*/
char **str[wCount+1];/*where the lines are being stored*/
int j=0;
while(!feof(file)){/*inserting lines*/
fscanf(file, "%s", &str[j]);
j++;
}
char *token, *cp;
int i;
int len;
for(i = 0; str[i]; i++){/*checking to insert words*/
len = strlen(*str[i]);
cp = xerox(*str[i]);
token = strtok(cp, delimiters);
if(!present(fIndex, token)){
insert(fIndex, i+1,token);
}
while(token!=NULL){
token = strtok(NULL, delimiters);
if(!present(fIndex, token)){
insert(fIndex, i+1,token);
}
}
i++;
}
fclose(file);
}
int strcmpigncase(char *s1, char *s2){/*checks words*/
for(;*s1==*s2;s1++,s2++){
if(*s1=='\0')
return 0;
}
return tolower(*s2)-tolower(*s2);
}
present(struct fileIndex* fIndex, char *findIt){/*finds if word is in structure*/
struct fileIndex* current = fIndex;
while(current!=NULL){
current = current -> next;
if(strcmpigncase(current -> str, findIt)==0){
return current -> lineNum;
}
}
return 0;
}
void insert(struct fileIndex *head, int num, char *insert){/*inserts word into structure*/
struct fileIndex* node = malloc(sizeof(struct fileIndex));
node -> str = insert;
node -> lineNum = num;
node -> next = head;
head = node;
}
#define IN_WORD 1
#define OUT_WORD 0
int wordcount(FILE *input)/*number of words in file*/
{
FILE *open = input;
int cur; /* current character */
int lc=0; /* line count */
int state=OUT_WORD;
while ((cur=fgetc(open))!=EOF) {
if (cur=='\n')
lc++;
if (!isspace(cur) && state == OUT_WORD) {
state=IN_WORD;
}
else if (state==IN_WORD && isspace(cur)) {
state=OUT_WORD;
}
}
return lc;
}
char *xerox(char *s){
int i = strlen(s);
char *buffer = (char *)(malloc(i+1));
if(buffer == NULL)
return NULL;
char *t = buffer;
while(*s!='\0'){
*t=*s;
s++; t++;
}
*t = '\0';
return buffer;
}
This code has a fairly high rate of problems. I'll dissect just the first few lines to give an idea:
void main(int argc, char **argv){
main should return int, not void. Probably not causing your problem, but not right either.
file = fopen(argv[1],"r");
You really need to check the value of argc before trying to use argv[1]. Invoking the program without an argument may well lead to a problem. Depending on how you've invoked it, this could be the cause of your problem.
struct fileIndex *fIndex = NULL;
Unless you've included some headers you haven't shown, this shouldn't compile -- struct fileIndex doesn't seem to have been defined (nor does it seem to be defined anywhere I can see in the code you'e posted).
delimiters = " .,;:!-";/*strtok chars to seperate*/
int wCount = wordcount(file);/*number of words in file*/
This (wordcount) reads to the end of the file, but does not rewind the file afterward.
char **str[wCount+1];/*where the lines are being stored*/
From your description, you don't really have any need to store lines (plural) at all. What you probably want is to read one line, then tokenize it and insert the individual tokens (along with the line number) into your index, then read the next line. From what you've said, however, there's no real reason to store more than one raw line at a time though.
int j=0;
while(!feof(file)){/*inserting lines*/
As noted above, you've previously read to the end of the file, and never rewound the file. Therefore, nothing inside this loop should ever execute, because as soon as you get here, feof(file) should return true. When/if you take care of that, this loop won't work correctly -- in fact, a loop of the form while (!feof(file)) is essentially always wrong. Under the circumstances, you want to check the result of your fscanf, with something like:
while (1 == fscanf(file, "%1023s", line))
...so you exit the loop when attempting to read fails.
fscanf(file, "%s", &str[j]);
What you have here is basically equivalent to the notorious gets -- you've done nothing to limit the input to the size of the buffer. As shown above, you normally want to use %[some_number]s, where some_number is one smaller than the size of the buffer you're using (though, of course, to do that you do need a buffer, which you don't have either).
You've also done nothing to limit the number of lines to the amount of space you've allocated (but, as with the individual lines, you haven't allocated any). I almost hesitate to mention this, however, because (as mentioned above) from your description you don't seem to have any reason to store more than one line anyway.
Your code also leaks all the memory it allocates -- you have calls to malloc, but not a single call to free anywhere.
Actually, some of the advice above is (at last more or less) wrong. It's looking at how to fix an individual line of code, but in reality you probably want to structure the code a bit differently in general. Rather than read the file twice, once to count the words, then read it again to index the words, you probably want to read a line at a time (probably with fgets, then break the line into words, and count each word as you insert it into your index. Oh, and you almost certainly do not want to use a linked-list for your index either. A tree or a hash-table would make a great deal more sense for the job.
I also disagree with the suggestion(s) in the direction of using a debugger on this code. A debugger is not likely to lead toward significantly better code -- it may help you find a few of the localized problems, but is unlikely to lead toward a significantly better program. Instead, I'd suggest a pencil and a piece of paper as the tools you really need to use. I believe your current problems stem primarily for not having thought about the problem enough to really understand what steps are needed to accomplish the goal, and a debugger isn't likely to help much in finding an answer to that question.
If you don't have a good debugger handy, a good fallback is to simply add a few printf statements at steps through the code, so you can see how far it gets before crashing.
In this code:
char **str[wCount+1];/*where the lines are being stored*/
int j=0;
while(!feof(file)){/*inserting lines*/
fscanf(file, "%s", &str[j]);
j++;
}
str is an array of pointers to char *s. In your loop you are reading each piece of input into a slot in it. There are a couple of problems.
I think there's a miscount in the number of *s vs. &s (I don't usually program with that many levels of pointer indirection to avoid having to think so hard about them ;-). &str[j] is the address of that array element, but that array element is a pointer to a pointer; now you have a pointer to a pointer to a pointer. If you had instead char *str[wCount+1], and read into str[j], I think it might match up. (Also I don't use fscanf much, so perhaps someone can confirm how best to use it.)
More obviously, you're not actually allocating any memory for the string data. You're only allocating it for the array itself. You probably want to allocate a fixed amount for each one (you can do that in the loop before each fscanf call). Remember that you're fscanf could in practice read more than that fixed size, resulting in another memory error. Again, working around that requires an expert in fscanf usage.
Hope this helps for a start. If the printf suggestion finds a more specific point in the code where it fails, add that to the question.

Implementing a string copy function in C

At a recent job interview, I was asked to implement my own string copy function. I managed to write code that I believe works to an extent. However, when I returned home to try the problem again, I realized that it was a lot more complex than I had thought. Here is the code I came up with:
#include <stdio.h>
#include <stdlib.h>
char * mycpy(char * d, char * s);
int main() {
int i;
char buffer[1];
mycpy(buffer, "hello world\n");
printf("%s", buffer);
return 0;
}
char * mycpy (char * destination, char * source) {
if (!destination || !source) return NULL;
char * tmp = destination;
while (*destination != NULL || *source != NULL) {
*destination = *source;
destination++;
source++;
}
return tmp;
}
I looked at some other examples online and found that since all strings in C are null-terminated, I should have read up to the null character and then appended a null character to the destination string before exiting.
However one thing I'm curious about is how memory is being handled. I noticed if I used the strcpy() library function, I could copy a string of 10 characters into a char array of size 1. How is this possible? Is the strcpy() function somehow allocating more memory to the destination?
Good interview question has several layers, to which to candidate can demonstrate different levels of understanding.
On the syntactic 'C language' layer, the following code is from the classic Kernighan and Ritchie book ('The C programming language'):
while( *dest++ = *src++ )
;
In an interview, you could indeed point out the function isn't safe, most notably the buffer on *dest isn't large enough. Also, there may be overlap, i.e. if dest points to the middle of the src buffer, you'll have endless loop (which will eventually creates memory access fault).
As the other answers have said, you're overwriting the buffer, so for the sake of your test change it to:
char buffer[ 12 ];
For the job interview they were perhaps hoping for:
char *mycpy( char *s, char *t )
{
while ( *s++ = *t++ )
{
;
}
return s;
}
No, it's that strcpy() isn't safe and is overwriting the memory after it, I think. You're supposed to use strncpy() instead.
No, you're writing past the buffer and overwriting (in this case) the rest of your stack past buffer. This is very dangerous behavior.
In general, you should always create methods that supply limits. In most C libraries, these methods are denoted by an n in the method name.
C does not do any run time bounds checking like other languages(C#,Java etc). That is why you can write things past the end of the array. However, you won't be able to access that string in some cases because you might be encroaching upon memory that doesn't belong to you giving you a segementation fault. K&R would be a good book to learn such concepts.
The strcpy() function forgoes memory management entirely, therefore all allocation needs to be done before the function is called, and freed afterward when necessary. If your source string has more characters than the destination buffer, strcpy() will just keep writing past the end of the buffer into unallocated space, or into space that's allocated for something else.
This can be very bad.
strncpy() works similarly to strcpy(), except that it allows you to pass an additional variable describing the size of the buffer, so the function will stop copying when it reaches this limit. This is safer, but still relies on the calling program to allocate and describe the buffer properly -- it can still go past the end of the buffer if you provide the wrong length, leading to the same problems.
char * mycpy (char * destination, char * source) {
if (!destination || !source) return NULL;
char * tmp = destination;
while (*destination != NULL || *source != NULL) {
*destination = *source;
destination++;
source++;
}
return tmp;
}
In the above copy implementation, your tmp and destination are having the same data. Its better your dont retrun any data, and instead let the destination be your out parameter. Can you rewrite the same.
The version below works for me. I'm not sure if it is bad design though:
while(source[i] != '\0' && (i<= (MAXLINE-1)))
{
dest[i]=source[i];
++i;
}
In general it's always a good idea to have const modifier where it's possible, for example for the source parameter.

Simple C string manipulation

I trying to do some very basic string processing in C (e.g. given a filename, chop off the file extension, manipulate filename and then add back on the extension)- I'm rather rusty on C and am getting segmentation faults.
char* fname;
char* fname_base;
char* outdir;
char* new_fname;
.....
fname = argv[1];
outdir = argv[2];
fname_len = strlen(fname);
strncpy(fname_base, fname, (fname_len-4)); // weird characters at the end of the truncation?
strcpy(new_fname, outdir); // getting a segmentation on this I think
strcat(new_fname, "/");
strcat(new_fname, fname_base);
strcat(new_fname, "_test");
strcat(new_fname, ".jpg");
printf("string=%s",new_fname);
Any suggestions or pointers welcome.
Many thanks and apologies for such a basic question
You need to allocate memory for new_fname and fname_base. Here's is how you would do it for new_fname:
new_fname = (char*)malloc((strlen(outdir)+1)*sizeof(char));
In strlen(outdir)+1, the +1 part is for allocating memory for the NULL CHARACTER '\0' terminator.
In addition to what other's are indicating, I would be careful with
strncpy(fname_base, fname, (fname_len-4));
You are assuming you want to chop off the last 4 characters (.???). If there is no file extension or it is not 3 characters, this will not do what you want. The following should give you an idea of what might be needed (I assume that the last '.' indicates the file extension). Note that my 'C' is very rusty (warning!)
char *s;
s = (char *) strrchr (fname, '.');
if (s == 0)
{
strcpy (fname_base, fname);
}
else
{
strncpy (fname_base, fname, strlen(fname)-strlen(s));
fname_base[strlen(fname)-strlen(s)] = 0;
}
You have to malloc fname_base and new_fname, I believe.
ie:
fname_base = (char *)(malloc(sizeof(char)*(fname_len+1)));
fname_base[fname_len] = 0; //to stick in the null termination
and similarly for new_fname and outdir
You're using uninitialized pointers as targets for strcpy-like functions: fname_base and new_fname: you need to allocate memory areas to work on, or declare them as char array e.g.
char fname_base[FILENAME_MAX];
char new_fname[FILENAME_MAX];
you could combine the malloc that has been suggested, with the string manipulations in one statement
if ( asprintf(&new_fname,"%s/%s_text.jpg",outdir,fname_base) >= 0 )
// success, else failed
then at some point, free(new_fname) to release the memory.
(note this is a GNU extension which is also available in *BSD)
Cleaner code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
const char *extra = "_test.jpg";
int main(int argc, char** argv)
{
char *fname = strdup(argv[1]); /* duplicate, we need to truncate the dot */
char *outdir = argv[1];
char *dotpos;
/* ... */
int new_size = strlen(fname)+strlen(extra);
char *new_fname = malloc(new_size);
dotpos = strchr(fname, '.');
if(dotpos)
*dotpos = '\0'; /* truncate at the dot */
new_fname = malloc(new_size);
snprintf(new_fname, new_size, "%s%s", fname, extra);
printf("%s\n", new_fname);
return 0;
}
In the following code I do not call malloc.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
/* Change this to '\\' if you are doing this on MS-windows or something like it. */
#define DIR_SYM '/'
#define EXT_SYM '.'
#define NEW_EXT "jpg"
int main(int argc, char * argv[] ) {
char * fname;
char * outdir;
if (argc < 3) {
fprintf(stderr, "I want more command line arguments\n");
return 1;
}
fname = argv[1];
outdir = argv[2];
char * fname_base_begin = strrchr(fname, DIR_SYM); /* last occurrence of DIR_SYM */
if (!fname_base_begin) {
fname_base_begin = fname; // No directory symbol means that there's nothing
// to chop off of the front.
}
char * fname_base_end = strrchr(fname_base_begin, EXT_SYM);
/* NOTE: No need to search for EXT_SYM in part of the fname that we have cut off
* the front and then have to deal with finding the last EXT_SYM before the last
* DIR_SYM */
if (!fname_base_end) {
fprintf(stderr, "I don't know what you want to do when there is no extension\n");
return 1;
}
*fname_base_end = '\0'; /* Makes this an end of string instead of EXT_SYM */
/* NOTE: In this code I actually changed the string passed in with the previous
* line. This is often not what you want to do, but in this case it should be ok.
*/
// This line should get you the results I think you were trying for in your example
printf("string=%s%c%s_test%c%s\n", outdir, DIR_SYM, fname_base_begin, EXT_SYM, NEW_EXT);
// This line should just append _test before the extension, but leave the extension
// as it was before.
printf("string=%s%c%s_test%c%s\n", outdir, DIR_SYM, fname_base_begin, EXT_SYM, fname_base_end+1);
return 0;
}
I was able to get away with not allocating memory to build the string in because I let printf actually worry about building it, and took advantage of knowing that the original fname string would not be needed in the future.
I could have allocated the space for the string by calculating how long it would need to be based on the parts and then used sprintf to form the string for me.
Also, if you don't want to alter the contents of the fname string you could also have used:
printf("string=%s%c%*s_test%c%s\n", outdir, DIR_SYM, (unsigned)fname_base_begin -(unsigned)fname_base_end, fname_base_begin, EXT_SYM, fname_base_end+1);
To make printf only use part of the string.
The basic of any C string manipulation is that you must write into (and read from unless... ...) memory you "own". Declaring something is a pointer (type *x) reserves space for the pointer, not for the pointee that of course can't be known by magic, and so you have to malloc (or similar) or to provide a local buffer with things like char buf[size].
And you should be always aware of buffer overflow.
As suggested, the usage of sprintf (with a correctly allocated destination buffer) or alike could be a good idea. Anyway if you want to keep your current strcat approach, I remember you that to concatenate strings, strcat have always to "walk" thourgh the current string from its beginning, so that, if you don't need (ops!) buffer overflow checks of any kind, appending chars "by hand" is a bit faster: basically when you finished appending a string, you know where the new end is, and in the next strcat, you can start from there.
But strcat doesn't allow to know the address of the last char appended, and using strlen would nullify the effort. So a possible solution could be
size_t l = strlen(new_fname);
new_fname[l++] = '/';
for(i = 0; fname_base[i] != 0; i++, l++) new_fname[l] = fname_base[i];
for(i = 0; testjpgstring[i] != 0; i++, l++) new_fname[l] = testjpgstring[i];
new_fname[l] = 0; // terminate the string...
and you can continue using l... (testjpgstring = "_test.jpg")
However if your program is full of string manipulations, I suggest using a library for strings (for lazyness I often use glib)

C: Proper syntax for allocating memory using pointers to pointers

This is my first time posting here, hopefully I will not make a fool of myself.
I am trying to use a function to allocate memory to a pointer, copy text to the buffer, and then change a character. I keep getting a segfault and have tried looking up the answer, my syntax is probably wrong, I could use some enlightenment.
/* My objective is to pass a buffer to my Copy function, allocate room, and copy text to it. Then I want to modify the text and print it.*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int Copy(char **Buffer, char *Text);
int main()
{
char *Text = malloc(sizeof(char) * 100);
char *Buffer;
strncpy(Text, "1234567890\n", 100);
Copy(&Buffer, Text);
}
int Copy(char **Buffer, char *Text)
{
int count;
count = strlen(Text)+1;
*Buffer = malloc(sizeof(char) * count);
strncpy(*Buffer, Text, 5);
*Buffer[2] = 'A'; /* This results in a segfault. "*Buffer[1] = 'A';" results in no differece in the output. */
printf("%s\n", *Buffer);
}
Your problem is simply one of precedence. The [] operator has higher precendence that unary-*, so the line is parsed as if it was:
*(Buffer[2]) = 'A';
...which is not what you want. You actually want the * to happen first, so you need to use parantheses:
(*Buffer)[2] = 'A';
Additionally, your strncpy() call is wrong. strncpy() does not nul-terminate the result if the number of characters copied is equal to the length; and since your memory comes straight from malloc(), there may not be a nul-terminator there already. strncpy() is actually the wrong tool in 99.99% of the cases that you will encounter - search on this site for numerous other answers explaining why.
A call to strncat() can be used instead:
(*Buffer)[0] = '\0'; /* Truncate to an empty string */
strncat(*Buffer, Text, 5);
*Buffer[2] is getting interpreted as *(Buffer[2]). What you want is (*Buffer)[2].
The problem is that *Buffer[2] means *(Buffer[2]) - you're trying to dereference the wrong pointer. You want to use (*Buffer)[2].

Resources