How to get a size of char**? [duplicate] - c

This question already has answers here:
Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]
(6 answers)
Can I know char-array-size to which a char pointer variable points? [duplicate]
(5 answers)
Closed 6 years ago.
I want to count size of my array (how many values/indexes are there).
I've found something like this on StackOverflow
char **sentences;
while ((c = fgetc(fp)) != EOF) {
... fill the array...
}
size_t w = sizeof(sentences); // this is wrong! it returns size of pointer (memory)
It gives me "w = 4" but my array has 6 records.
I need this for "for loop" to print my results (tried to count every loop in "while", but I got it in different function and I don't know to return 2 values in array [count|array of strings]).
I will be happy for any idea how to print the whole array.

You can return your actual count like this:
#include <stdio.h>
#include <stdlib.h>
char **doSomething(size_t *count) {
char **sentences;
// Mock initialization of sentences, please skip :-)
sentences = (char **)calloc(13, sizeof(char *));
for (int i = 0; i < 13; i++) {
sentences[i] = (char *)calloc(8, sizeof(char));
sprintf(sentences[i], "quux-%d", i); // Just filling in some foobar here.
}
// ---------
*count = 13; // <-- Look here, we're dereferencing the pointer first.
return sentences;
}
int main(int argc, char **argv) {
size_t size;
char **res;
// Sending the address of size, so the function can write there.
res = doSomething(&size);
for(size_t i = 0; i < size; i++)
printf("res[%lu]: %s\n", i, res[i]); // You should see the filler outputted to stdout.
return 0;
}

Related

Returning pointer to array doesn't give expected output in c [duplicate]

This question already has answers here:
returning a local variable from function in C [duplicate]
(4 answers)
Closed 5 years ago.
#include <stdio.h>
int* createReverseArray(int *array, int size)
{
int i;
int newArray[size];
for(i=size-1; i>=0; i--)
{
newArray[i] = array[size-i-1];
}
return newArray;
}
int main(void) {
int myArray[] = {1,2,3,5,1};
int myArray2[] = {1,2,3,4,2,1};
int i;
int size = sizeof(myArray)/sizeof(int);
printf("Size: %d\n", size);
int* newArray = createReverseArray(myArray, size);
for(i=0; i<size; i++)
{
printf("%d, ", newArray[i]);
}
return 0;
}
I printed the array within the createReverseArray function and got the correct output, but when I return the pointer to the array and then try to print the results, I think it's printing pointers to each array spot? I'm not quite sure.
This returns:
Size: 5
12341002, 1, -10772231820, -1077231812, 1074400845,
newarray is an automatic local variable. It will no longer exists once function return. Returning pointer to an automatic local variable invoke undefined behaviour and in this case nothing good can be expected.
You can allocate memory diynamically and then return pointer to it
int *newArray = malloc(sizeof(int)*size);

Storing char* array size in an int counter [duplicate]

This question already has answers here:
Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]
(6 answers)
Closed 6 years ago.
Well, I have the problem with the data updating in my counter int x. I am passing a lot of char* strings to my function, e.g. when I pass first char* of the length of 8, int x will be 8. Then if I pass the next char* of the length of 11, x still will hold the value of 8. Any advice on fixing it?
bool check(const char* word)
{
char checker[LENGTH+1];
int x = sizeof(word);
for(int a=0; a<x; a++) {
checker[a] = word[a];
}
for(int i=0; i < x-1; i++) {
//check if all chars are lower-case
if(checker[i] < 'a' && checker[i] != '\'') {
checker[i] = tolower(checker[i]);
}
}
}
sizeof(word) is giving you the size of your pointer. Use strlen instead to get the length of the string.
Also a style note, x isn't a great name for a variable that stores a string length, I'd name it something more to do with what it's actually used for.

Read strings from console [duplicate]

This question already has answers here:
How to read string from keyboard using C?
(6 answers)
Closed 8 years ago.
I wanna write a program with an array of pointers to char where I store strings read from the console in it. A string is determined by \n. Any ideas how I can do this?
Code with mix of pseudocode so far:
char** arr;
arr = malloc(sizeof(char*) * 5);
arr = malloc(sizeof(char) * 10);
while (No \n read) {
// Store the string in the array
}
I really have no clue how to do this.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
char **arr;
arr = malloc(sizeof(char*) * 5);//for 5 string
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);//reserved storage space length 9
scanf("%9[^\n]%*c", arr[i]);//Read until \n, and discard \n
}
printf("\n");
//check print and free
for(i=0;i<5;++i){
puts(arr[i]);
free(arr[i]);
}
free(arr);
return 0;
}
int i, n;
char **arr;
arr = malloc(sizeof(char*) * 5);
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);
}
i=0;
while(i<5 && 1==scanf("%9[^\n]%*c", arr[i]))
++i;
n = i;
printf("\n");
//check print
for(i=0;i<n;++i){
puts(arr[i]);
}
//deallocate
for(i=0;i<5;++i)
free(arr[i]);
free(arr);
You can use this one.
Creating the new char variable and allocate the memory for that. Then get the input like this.
p=(char *)malloc(100);
while ( (*p=getchar())!='\n')p++;
*arr[0]=p;
If you want to create the multiple lines then allocate the memory for that char variable dynamically then store that in the array of pointers.

Why won't all of my char array get passed (in C)? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C sizeof a passed array
Why sizeof(param_array) is the size of pointer?
I'm new to C, and am a little confused by the type system. I'm trying to write some code to print the number of lower case characters in a string, but only an int-sized piece of my array gets passed to the cntlower function. Why is this?
#include "lecture2.h"
int main(void){
int lowerAns;
char toCount[] = "sdipjsdfzmzp";
printf("toCount size %i\n", sizeof(toCount));
lowerAns = cntlower(toCount);
printf("answer %i\n", lowerAns);
}
int cntlower(char str[]) {
int lowers = 0;
int i = 0;
printf("str size %i\n", sizeof(str));
printf("char size %i\n", sizeof(char));
for(i = 0; i < (sizeof(str)/sizeof(char)); i++) {
if(str[i] >= 'a' && str[i] <= 'z') {
lowers++;
}
}
return lowers;
}
As it is, the output is currently:
toCount size 13
str size 4
char size 1
answer 4
I'm sure the reason for this is obvious for some of you, but unfortunately it isn't for me!
A char str[] argument to a function is actually syntactic sugar for a char*, so sizeof(str) == sizeof(char*). That happens to coincide with sizeof(int) on your platform.

How to empty a 2d char array in C?

I am still new with C and I am trying to empty a 2d char array. Here is the declaration:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = (char*) calloc (strlen(buf), sizeof(char*));
}
Here is where I try to empty it:
void make_empty(char **arg_array)
{
int i;
for(i = 0; i <= BUFSIZ; i++)
{
arg_array[i][0] = '\0';
}
return;
}
Any help is appreciated
So, am I doing it right because this seems to give me segfaults when I try to add data to the array again and then print it?
Empty is just to have it empty - how can I explain more? lol
Try this:
void make_empty(char **arg_array, int rows, int cols)
{
int i,j;
for(i = 0; i <rows; i++)
{
for(j=0; j<cols;j++)
{
arg_array[i][j] = '\0';
}
}
return;
}
Where rows is number of rows and cols number of cols of your array.
P.S. This function clears the whole array as you should always do. As I commented before, putting '\0' as a first char in string does not clear the whole row, it only makes the rest of it ,,invisible'' for functions like printf. Check this link for more information: http://cplusplus.com/reference/clibrary/cstdio/printf/
There is no need to empty it. Often in C, memory allocation is done with malloc which simply returns to you a block of memory which is deemed owned by the caller. When calloc is called, as well as returning you a block of memory, the memory is guaranteed to be initialized to 0. This means for all intents and purposes it is already 'empty'.
Also I'm not quite sure if your code does what you are intending. Let me explain what it does at the moment:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
This line is simply wrong. In C, there is no need to cast pointers returned from calloc because they are of type void *, which is implicitly casted to any other pointer type. In this case, you are storing it in a char type which makes no sense. If you do this:
char ** arg_array = calloc(strlen(buf), sizeof (char**));
Then it allocates an array of pointers of strlen(buf) length. So if buf is "hello" then you have now allocated an array which can store 5 pointers.
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = calloc (strlen(buf), sizeof(char*));
}
Again, I have removed the redundant cast. What this does is populates the array allocated earlier. Each index of the array now points to a char string of strlen(buf) * sizeof(char *) length. This is probably not what you want.
Your question is more clear to me now. It appears you want to remove the strings after populating them. You can do it two ways:
Either free each of the pointers and allocate more space later as you did before
Or set the first character of each of the strings to a null character
To free the pointers:
for(i = 0; i<(strlen(buf)); i++)
{
free(arg_array[i]);
}
To set the first character of each string to a null character:
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i][0] = '\0';
}
That is the same code as what you have originally and should be fine.
As proof, the following code will run without errors:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char * buf = "hello";
char ** arg_array = calloc(strlen(buf), sizeof (char**));
unsigned int i;
for(i = 0; i < strlen(buf); i++) {
arg_array[i] = calloc(strlen(buf),
sizeof(char *));
}
for(i = 0; i < strlen(buf); i++) {
arg_array[i][0] = '\0';
}
for(i = 0; i < strlen(buf); i++) {
free(arg_array[i]);
}
free(arg_array);
return EXIT_SUCCESS;
}
If your code is segfaulting, the problem is coming from somewhere else. Did you overwrite the arg_array variable? Are you sure BUFSIZE is equal to strlen(buf)?

Resources