/*dynamically allocating memory in called funcion and freeing in caller*/

char**  memall(int ns);

#define Max 20
#include<stdio.h>

int main()
{
        char **s;
        int i,ns;
        printf("no of string you want to store");
        scanf("%d",&ns);
        s=memall(ns);
        for(i=0;i<ns;i++)
        printf("addrs =%u and string=%s\n",(s+i),s[i]);
        for(i=0;i<ns;i++)
        free(s[i]);
        free(s);
       /* s=NULL;
        for(i=0;i<ns;i++)
        printf("%s\n",s[i]);
        *///dont try to access after freeing.
}

char**  memall(int ns)
        {
                char **p;
                char temp[100];
                int i, j;
                int c;
                p=(char **)malloc(ns*sizeof(char *));
                for(i=0;i<ns;i++)
                        printf("%u\n",p+i);
                for(i=0;i<ns;i++)
                {
                        j=0;
                        printf("\nenter the string %d",i+1);
                        while((c=getchar())=='\n'||c==' '||c=='\t');
                        temp[j++]=c;
                        while((c=getchar())!='\n')
                                temp[j++]=c;
                        temp[j] = '\0';
                        p[i]=(char *)malloc(strlen(temp) + 1);
                        printf("%u\n",p[i]);
                        strcpy(p[i],temp);
                }
                return p;
        }

OUT PUT:

[Shark@localhost Dyns]$ gcc daarrof_chrptrs_nl.c
[Shark@localhost Dyns]$ ./a.out
no of string you want to store6
155586568
155586572
155586576
155586580
155586584
155586588

enter the string 1Tom Gunn
155586600
enter the string 2Aia
155586616
enter the string 3Narue
155586632
enter the string 4Ancient Dragon
155586648
enter the string 5Yellow Snow
155586672
enter the string 6C surfer
155586688

addrs =155586568 and string=Tom Gunn
addrs =155586572 and string=Aia
addrs =155586576 and string=Narue
addrs =155586580 and string=Ancient Dragon
addrs =155586584 and string=Yellow Snow
addrs =155586588 and string=C surfer

if we observe the out put the malloc in the loop at line 44 its allocating the memory with a 16 byte difference in its previous allocation and next allocation.

is there any reason underlying for so.

my secong question is

if i need a pointer to an array that increments the no of locations that is known at run time, how can i create it.

#define NOC 4
int (*ptr)[NOC] ;
ptr = ( int (*) [NOC] ) malloc ( 1024 );
here NOC is known at complile time but i want to decide at runtime.

Just curious, If you run this program what's your outcome

#include <stdlib.h>
#include <stdio.h>

#define ARR_SIZE 10

int main()
{
	int i = 0;
	unsigned long *myint = NULL;
	myint = (unsigned long*)malloc(ARR_SIZE * sizeof(unsigned long));
	

	for (i = 0; i < ARR_SIZE; ++i)
	{
		fprintf(stdout, "addr->%p\n", (void*)myint++);

	}
	exit(EXIT_SUCCESS);
}

I got

addr->0x8c7010
addr->0x8c7018
addr->0x8c7020
addr->0x8c7028
addr->0x8c7030
addr->0x8c7038
addr->0x8c7040
addr->0x8c7048
addr->0x8c7050
addr->0x8c7058

on a 64 bit Linux box which makes sense since its an array and the addresses have to be consistent.

Then try this one

#include <stdlib.h>
#include <stdio.h>

#define ARR_SIZE 10

int main()
{
	int i = 0;
	unsigned long *myint[ARR_SIZE];

	for (i = 0; i < ARR_SIZE; ++i)
	{
		myint[i] = (unsigned long*)malloc(ARR_SIZE * sizeof(unsigned long));
		fprintf(stdout, "addr->%p\n", (void*)myint[i]);
	}
	
	
	exit(EXIT_SUCCESS);
}

My output was

addr->0xfe4010
addr->0xfe4070
addr->0xfe40d0
addr->0xfe4130
addr->0xfe4190
addr->0xfe41f0
addr->0xfe4250
addr->0xfe42b0
addr->0xfe4310
addr->0xfe4370

Why the bigger range? It really depends on how the memory manager doles out memory. In the first example it was required that the memory lie within the requirements of a unsigned long array so the memory manager had allocated it that way...the second example isn't so constricted because its an array of unsigned long pointers....

Just curious, If you run this program what's your outcome

#include <stdlib.h>
#include <stdio.h>

#define ARR_SIZE 10

int main()
{
	int i = 0;
	unsigned long *myint = NULL;
	myint = (unsigned long*)malloc(ARR_SIZE * sizeof(unsigned long));
	

	for (i = 0; i < ARR_SIZE; ++i)
	{
		fprintf(stdout, "addr->%p\n", (void*)myint++);

	}
	exit(EXIT_SUCCESS);
}

I got

addr->0x8c7010
addr->0x8c7018
addr->0x8c7020
addr->0x8c7028
addr->0x8c7030
addr->0x8c7038
addr->0x8c7040
addr->0x8c7048
addr->0x8c7050
addr->0x8c7058

on a 64 bit Linux box which makes sense since its an array and the addresses have to be consistent.

Then try this one

#include <stdlib.h>
#include <stdio.h>

#define ARR_SIZE 10

int main()
{
	int i = 0;
	unsigned long *myint[ARR_SIZE];

	for (i = 0; i < ARR_SIZE; ++i)
	{
		myint[i] = (unsigned long*)malloc(ARR_SIZE * sizeof(unsigned long));
		fprintf(stdout, "addr->%p\n", (void*)myint[i]);
	}
	
	
	exit(EXIT_SUCCESS);
}

My output was

addr->0xfe4010
addr->0xfe4070
addr->0xfe40d0
addr->0xfe4130
addr->0xfe4190
addr->0xfe41f0
addr->0xfe4250
addr->0xfe42b0
addr->0xfe4310
addr->0xfe4370

Why the bigger range? It really depends on how the memory manager doles out memory. In the first example it was required that the memory lie within the requirements of a unsigned long array so the memory manager had allocated it that way...the second example isn't so constricted because its an array of unsigned long pointers....

i agree with that.

can you please suggest me on how my second problem is solved.

if i need a pointer to an array that increments the no of locations that is known at run time, how can i create it.

#define NOC 4
int (*ptr)[NOC] ;
ptr = ( int (*) [NOC] ) malloc ( 1024 );
here NOC is known at complile time but i want to decide at runtime.

Not really sure what you want...is it something like this

#include <stdio.h>
#include <stdlib.h>

#define ARR_SIZE 10

int main(int argc, char**argv)
{
	int jump = 0, i = 0;
	int *intptr = (int*)NULL;
	int *origptr = intptr;

	intptr = (int*)malloc(ARR_SIZE * sizeof(int));

	for (i = 0; i < ARR_SIZE; ++i)
	{
		intptr[i] = i + 1;
	}

	fprintf(stdout, "enter jump value 0 - %d-> ", (ARR_SIZE - 1));
	fscanf(stdin, "%d", &jump);

	intptr += jump;

	fprintf(stdout, "ans->%d\n", *intptr);

	free(origptr);
	origptr = (int*)NULL;
	intptr = (int*)NULL;
	exit(EXIT_SUCCESS);
}

Not really sure what you want...is it something like this

#include <stdio.h>
#include <stdlib.h>

#define ARR_SIZE 10

int main(int argc, char**argv)
{
	int jump = 0, i = 0;
	int *intptr = (int*)NULL;
	int *origptr = intptr;

	intptr = (int*)malloc(ARR_SIZE * sizeof(int));

	for (i = 0; i < ARR_SIZE; ++i)
	{
		intptr[i] = i + 1;
	}

	fprintf(stdout, "enter jump value 0 - %d-> ", (ARR_SIZE - 1));
	fscanf(stdin, "%d", &jump);

	intptr += jump;

	fprintf(stdout, "ans->%d\n", *intptr);

	free(origptr);
	origptr = (int*)NULL;
	intptr = (int*)NULL;
	exit(EXIT_SUCCESS);
}

just like this, but i want it in two dimentional space.

i require a pointer to array of elements ( the number of elements the pointer should be incremented is not known at compile time).

int (*p)[5];
increments by 5 locations
int (*p)[6];
increments by 6 locations

slly i want a pointer to an array but how many elements it should be incremented will be decided at runtime.

dono we have any applications which demands that.

i am just curious.

Thanks.

Just do the "subscripting" "by hand".

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.