I'm confusing about the different sizeof() return value after function check() calls. And buf exactly the same as buffer based on the printf() for each char. Any reply is awesome! Thx.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void check(char *buf)
{
printf("%d \n", sizeof(buf)); // **output 8**
}
int main(int argc, char *argv[])
{
char buffer[] = "\x64\x49\x00\x55\x33\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33";
printf("%d\n", sizeof(buffer)); // **output 33**
check(buffer);
}
In function check buffer is a pointer to the char and its size is 8
In the main furnctions buffers is the 33 elements char array and its size is 33
To get the length of the C string use strlen function.
Generally there is no way of getting the size of the array referenced by the pointer. You need to pass the size as a anothother parameter.
In your example:
void check(char *buf, size_t size)
{
printf("%zu \n", size);
}
int main(int argc, char *argv[])
{
char buffer[] = "\x64\x49\x00\x55\x33\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33\x64\x49\x00\x00\x00\x55\x33\x33";
printf("%d\n", sizeof(buffer)); // **output 33**
check(buffer, sizeof(buffer));
}
Related
I'm totally new in C and I want to write a function :
#include <unistd.h> //import write...
void ft_putchar(char str[20]) {
write(1, &str, 19);
}
char main() {
char str2[20] = "GeeksforGeeks";
ft_putchar(str2[20]);
return(0);
}
Hope this will help you a bit :)
#include <unistd.h> //import write...
void ft_putchar(char *str) { // the size of the buffer is not required
write(1, str, strlen(str)); // 2nd argument is a char*, not a char **
// 3rd one is the actual length of your
// string, not the size of the buffer
}
int main() {
char str2[20] = "GeeksforGeeks";
ft_putchar(str2); // the size of the buffer is not required
return(0);
}
#include <string.h>
void foo (char *bar)
{
char c[12];
strcpy(c, bar); // no bounds checking
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}
Another ACTUAL option:
void foo (char *bar)
{
char c[12];
snprintf(c, sizeof c, "%s", bar);
}
The functions strncpy do not ensure the resulting strings are terminated by a NULL character and therefore you can have a bad resulting string.
Check whether the length of the bar is less than length of c.
code:
#include <string.h>
void foo (char *bar)
{
char c[12];
if ( strlen( bar ) < sizeof c ) {
printf("avoiding buffer overflow");
strcpy( c, bar );
}
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}
I made it safe. Otherwise it's doing just the same thing as your original app, that is: nothing.
int main (int argc, char **argv)
{
return 0;
}
I need to pass a pre-allocated array of strings as a function parameter, and strcpy() to each of the strings within the string array, as in this example:
static void string_copy(char * pointer[]) {
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
int main(int argc, const char * argv[]) {
char my_array[10][100];
string_copy(my_array);
printf("%s%s\n", my_array[0], my_array[1]);
}
And the resulting printed string would be 'Hello world'.
How do I pass a pre-allocated string array and fill out each string within a function as shown above?
When you are doing string_copy(my_array), you are passing a char (*)[100], i.e. pointer to char[100] array to your function. But your function is expecting a char *[], i.e. array of char pointers, because you have defined your function that way.
You can fix this by making changes so that your function (string_copy()) expects a char (*)[100], instead of a char *[].
For this, you can change your function definition as:
/* Your my_array gets converted to pointer to char[100]
so, you need to change your function parameter
from `char *pointer[]` to `char (*pointer)[100]`
*/
/* static void string_copy(char *pointer []) */
static void string_copy(char (*pointer) [100])
{
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
* Alternative Solution *
A different design/solution would be to change in your main() function so that you are actually passing a char *[], which decays into a char ** - which is fine - to string_copy(). This way you would NOT have to change your string_copy() function.
int main(int argc, const char * argv[]) {
char my_array[10][100];
int tot_char_arrs, i;
char *char_arr_ptr[10];
/* Get total number of char arrays in my_array */
tot_char_arrs = sizeof(my_array) / sizeof(my_array[0]);
// Store all char *
for (i = 0; i < tot_char_arrs; i++)
char_arr_ptr[i] = my_array[i];
/* Actually passing a char *[].
it will decay into char **, which is fine
*/
string_copy(char_arr_ptr);
printf("%s%s\n", my_array[0], my_array[1]);
}
you need to use a pointer to the array. here is an example with 1 dimension array:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static void string_copy(char **pointer) {
strcpy(pointer[0], "Hello ");
}
int main(int argc, const char * argv[]) {
char my_array[10];
char * p_array = my_array;
string_copy(&p_array);
printf("%s\n", my_array);
}
Your function can simply accept matrix dimensions and pass a const char * that stores the array of literals (pre-allocated) strings:
#include <stdio.h>
#include <string.h>
#define STRINGS_LENGTH 100
static void string_copy(size_t n, size_t m, char pointer[n][m], const char *strings_to_copy[])
{
for (size_t i=0; i< n; i++)
{
strcpy(pointer[i], strings_to_copy[i]);
}
}
int main( void )
{
const char *strings[] = { "hello", "World" };
char my_array[sizeof(strings)/sizeof(strings[0])][STRINGS_LENGTH];
string_copy(sizeof(strings)/sizeof(strings[0]), STRINGS_LENGTH, my_array, strings);
printf("%s %s\n", my_array[0], my_array[1]);
}
You can also change the structure of your code using dynamic allocation for your output array like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
static bool string_copy(char *pointer[], const char *strings_to_copy[], size_t strings)
{
for (size_t i=0; i< strings; i++)
{
pointer[i] = malloc(strlen(strings_to_copy[i])+1);
if (pointer[i] != NULL)
strcpy(pointer[i], strings_to_copy[i]);
else
return false;
}
return true;
}
int main(void)
{
const char *strings[] = { "hello", "World" };
char *my_array[sizeof(strings)/sizeof(strings[0])] = {0};
if (string_copy(my_array, strings, sizeof(strings)/sizeof(strings[0])) )
{
printf("%s %s\n", my_array[0], my_array[1]);
}
for (size_t i = 0; i<sizeof(strings)/sizeof(strings[0]); i++)
free (my_array[i]);
}
I am trying to add an int to a Multi-dimensional char Array. After reading the link below I would think I can use sprintf. If I can't use sprintf what is another way I can do this?
http://www.cplusplus.com/reference/cstdio/sprintf/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
//{"TYPE", "ID", "SCOPE", "VALUE"}
char *symbol_table_variables[503][4];
int scope = 0;
int lower_bound_of_big_boy_counter = 0;
sprintf (symbol_table_variables[lower_bound_of_big_boy_counter][2], "%d", scope);
printf("symbol_table_variables[lower_bound_of_big_boy_counter][2] %s \n",
symbol_table_variables[lower_bound_of_big_boy_counter][2]);
return 0;
}
An update.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
//{"TYPE", "ID", "SCOPE", "VALUE"}
char *symbol_table_variables[503][4] = {0};
int scope = 5;
int lower_bound_of_big_boy_counter = 0;
char scope_char[80] = {0};
sprintf (scope_char, "%d", scope);
printf("scope_char %s \n", scope_char);
symbol_table_variables[lower_bound_of_big_boy_counter][2] =
malloc(strlen(scope_char)+1);
strcpy(symbol_table_variables[lower_bound_of_big_boy_counter][2],
scope_char);
memset(scope_char, 0, 80);
//sprintf (symbol_table_variables[lower_bound_of_big_boy_counter][2], "%d", scope);
printf("symbol_table_variables[lower_bound_of_big_boy_counter][2] is %s \n",
symbol_table_variables[lower_bound_of_big_boy_counter][2]);
return 0;
}
symbol_table_variables[lower_bound_of_big_boy_counter][2] has no memory allocated to it you you are invoking undefined behavior.
One solution would be to allocate some memory
symbol_table_variables[lower_bound_of_big_boy_counter][2] = malloc(32);
printf (symbol_table_variables[lower_bound_of_big_boy_counter][2], "%d", scope);
That isn't great because you don't really know how much memory you need.
I'd be questioning the need for a 2D array of strings...
This question already has answers here:
Passing address of array as a function parameter
(6 answers)
Closed 9 years ago.
I'm writing a function that gets a string, allocates memory on the heap that's enough to create a copy, creates a copy and returns the address of the beginning of the new copy.
In main I would like to be able to print the new copy and afterwards use free() to free the memory. I think the actual function works although I am not the char pointer has to be static, or does it?
The code in main does not work fine...
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
int make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(sizeof(arr));
int i=0;
for(;i<sizeof str_ptr/sizeof(char);i++)
str_ptr[i]=arr[i];
return (int)str_ptr;
}
OK, so based on the comments. A revised version:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
char *ptr=make_copy(arrr);
printf("%s",ptr);
getchar();
return 0;
}
char* make_copy(char arr[])
{
static char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
int i=0;
for(;i<strlen(arr)+1;i++)
str_ptr[i]=arr[i];
return str_ptr;
}
Or even better:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={"abcdef\0"};
printf("%s",make_copy(arrr));
getchar();
return 0;
}
char* make_copy(char arr[])
{
char *str_ptr;
str_ptr=(char*)malloc(strlen(arr)+1);
return strcpy(str_ptr,arr);
}
You're on the right track, but there are some issues with your code:
Don't use int when you mean char *. That's just wrong.
Don't list characters when defining a string, write char arrr[] = "abcdef";
Don't scale string alloations by sizeof (char); that's always 1 so it's pointless.
Don't re-implement strcpy() to copy a string.
Don't cast the return value of malloc() in C.
Don't make local variables static for no reason.
Don't use sizeof on an array passed to a function; it doesn't work. You must use strlen().
Don't omit including space for the string terminator, you must add 1 to the length of the string.
UPDATE Your third attempt is getting closer. :) Here's how I would write it:
char * make_copy(const char *s)
{
if(s != NULL)
{
const size_t size = strlen(s) + 1;
char *d = malloc(size);
if(d != NULL)
strcpy(d, s);
return d;
}
return NULL;
}
This gracefully handles a NULL argument, and checks that the memory allocation succeeded before using the memory.
First, don't use sizeof to determine the size of your string in make_copy, use strlen.
Second, why are you converting a pointer (char*) to an integer? A char* is already a pointer (a memory address), as you can see if you do printf("address: %x\n", ptr);.
sizeof(arr) will not give the exact size. pass the length of array to the function if you want to compute array size.
When pass the array to function it will decay to pointer, we cannot find the array size using pointer.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *strdup(const char *str)
{
char *s = (char*)malloc(strlen(str)+1);
if (s == NULL) return NULL;
return strcpy(s, str);
}
int main()
{
char *s = strdup("hello world");
puts(s);
free(s);
}
Points
~ return char* inside of int.
~ you can free the memory using below line
if(make_copy!=NULL)
free(make_copy)
Below is the modified code.
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
char* make_copy(char arr[]);
int main()
{
char arrr[]={'a','b','c','d','e','f','\0'};
char *ptr;
ptr=make_copy(arrr,sizeof(arrr)/sizeof(char));
printf("%s",ptr);
printf("%p\n %p",ptr,arrr);
getchar();
return 0;
}
char* make_copy(char arr[],int size)
{
char *str_ptr=NULL;
str_ptr=(char*)malloc(size+1);
int i=0;
for(;i<size;i++)
str_ptr[i]=arr[i];
str_ptr[i]=0;
return str_ptr;
}