How to assign some part of dynamic array to whole static array - c

The size of dynamic array is the twice the size of static array. I want to assign the values which starts from (N/2)-1 to N-1 of dynamic array to whole static array.
The only way is copying the values with a loop?
My code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
int N=100, pSize=4, lSize, i;
double *A;
lSize=N/sqrt(pSize);
/* memory allocation */
A=(double*)malloc(sizeof(double)*N);
double B[lSize];
/* memory allocation has been done */
/* initilize arrays */
for(i=0; i<lSize; i++){
B[i]=rand()% 10;
}
A=B;
for (i=0; i<lSize; i++){
fprintf(stdout,"%f\n", A[i]);
}
return 0;
}

You can use the memcpy function to copy the data. For your example you want to copy the last half of A to B so could do something like:
memcpy(&B[0], &A[lSize-1], lSize * sizeof(double));
Note: On the MinGW compiler I was using, it was requiring that I declare the destination as &B[0], I thought I could get away with just B. It may be due to configuration I have (I don't use the C compiler all that much, normally just use g++ for quick C++ test cases).

You can use memcpy to copy contiguous chunks of memory around.

Your program leaks your allocation, which is probably bad - is that A=B intended to be where you would put the code that copies the array?
It may be possible, depending on your architecture, to do a copy without a CPU loop (via a call to a DMA engine or something). In standard C, you have no choice but to loop. You can either do it yourself or you can call memcpy(3), memmove(3), or bcopy(3) if you prefer to use the library's implementations.

As said, you need to use memcpy:
#define N 100
int staticarray[N];
int *pointer = (int*) malloc( sizeof(int)*N*2 );
memcpy( staticarray, (pointer + ((N/2) - 1)), sizeof(int)*N );

Related

Is it possible to assign data to this "static array" in C using for-loop?

There is a line of code inside a method similar to:
static char data[] = "123456789";
I want to fill the above data array with a million characters not just nine.
But since it is tedious to type it, I want to do that in for loop.
Is that possible to do it keeping it as "static char data[]"?
edit:
static char data[1000000];
for(int i=0; i<1000000; i++)
{
data[i] = 1;
}
There are multiple ways to achieve this in C:
you can declare the global static array as uninitialized, write an initialization function and call this function at the beginning of the program. Unlike C++, C does not have a standard way to invoke such an initialisation function at program startup time, yet some compilers might provide an extension for this.
static char data[1000000];
void init_data(void) {
//the loop below will generate the same code as
//memset(data, 1, sizeof data);
for (int i = 0; i < 1000000; i++) {
data[i] = 1;
}
}
int main() {
init_data();
...
}
you can change your program logic so the array can be initialized to 0 instead of 1. This will remove the need for an initialization function and might simplify the code and reduce the executable size.
you can create the initializer for the array using an external program and include its output:
static char data[1000000] = {
#include "init_data.def"
};
you can initialize the array using macros
#define X10(s) s,s,s,s,s,s,s,s,s,s
#define X100(s) X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s),X10(s)
#define X1000(s) X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s),X100(s)
#define X10000(s) X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s),X1000(s)
#define X100000(s) X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s),X10000(s)
static char data[1000000] = {
X100000(1), X100000(1), X100000(1), X100000(1), X100000(1),
X100000(1), X100000(1), X100000(1), X100000(1), X100000(1),
};
Note however that this approach will be a stress test for both your compiler and readers of your code. Here are some timings:
clang: 1.867s
gcc: 5.575s
tcc: 0.690s
The last 2 solutions allow for data to be defined as a constant object.
Is that possible to do it keeping it as "static char data[]"?
No, you have to specify the size explicitly. If you wish to compile-time initialize the array rather than assigning to it in run-time with a for loop or memset, you can use tricks such as this.
Another option might be to use dynamic allocation with malloc instead, but then you have to assign everything in run-time.
You can define statically allocated arrays in various ways, incidentally, this has nothing to do with the static keyword, see this if you need more information about static variables. The following discussion won't have anything to do with that, hence I will be omitting your static keyword for simplicity.
An array declared as:
char data[] = "123456789";
is allocated in the stack in the compile time. Compiler can do that since the size of the array is implicitly given with the string "123456789" to be 10 characters, 9 for the data and +1 for the terminating null character.
char data[];
On the other hand, will not compile, and your compiler will complain about missing array sizes. As I said, since this declaration allocates the array in the compile time, your compiler wants to know how much to allocate.
char data[1000000];
This on the other hand will compile just fine. Since now the compiler knows how much to allocate. And you can assign elements as you did in a for loop:
for(int i=0; i<1000000; i++)
{
data[i] = 1;
}
Note:
An array of million chars has quite a respectable size, typically 1Mb, and may overflow your stack. Whether or not that it actually will depends on pretty much everything that it can depend on, but it certainly will rise some eyebrows even if your code works fine. And eventually, if you keep increasing the size you will end up overflowing your buffer.
If you have truly large arrays you need to work with, you can allocate them on the heap, i.e., in the wast empty oceans of your ram.
The part above hopefully should have answered your question. Below is simply an alternative way to assign a fixed value, such as your (1), to a char array, instead of using for loops. This is nothing but a more convenient way (and perhaps a better practice), you are free to ignore it if it causes confusion.
#include <string.h>
#define SIZE 100000
// Create the array, at this point filled with garbage.
static char data[SIZE];
int main( void )
{
// Initialise the array: assigns *integer 1* to each element.
memset( data, 1, sizeof data )
//^___ This single line is equivalent of:
// for ( int i = 0; i < SIZE; i++ )
// {
// data[i] = 1;
// }
.
.
.
return 0;
}

cudaMalloc gives a NULL pointer [duplicate]

I'm new to CUDA/C and new to stack overflow. This is my first question.
I'm trying to allocate memory dynamically in a kernel function, but the results are unexpected.
I read using malloc() in a kernel can lower performance a lot, but I need it anyway so I first tried with a simple int ** array just to test the possibility, then I'll actually need to allocate more complex structs.
In my main I used cudaMalloc() to allocate the space for the array of int *, and then I used malloc() for every thread in the kernel function to allocate the array for every index of the outer array. I then used another thread to check the result, but it doesn't always work.
Here's main code:
#define N_CELLE 1024*2
#define L_CELLE 512
extern "C" {
int main(int argc, char **argv) {
int *result = (int *)malloc(sizeof(int));
int *d_result;
int size_numbers = N_CELLE * sizeof(int *);
int **d_numbers;
cudaMalloc((void **)&d_numbers, size_numbers);
cudaMalloc((void **)&d_result, sizeof(int *));
kernel_one<<<2, 1024>>>(d_numbers);
cudaDeviceSynchronize();
kernel_two<<<1, 1>>>(d_numbers, d_result);
cudaMemcpy(result, d_result, sizeof(int), cudaMemcpyDeviceToHost);
printf("%d\n", *result);
cudaFree(d_numbers);
cudaFree(d_result);
free(result);
}
}
I used extern "C"because I could't compile while importing my header, which is not used in this example code. I pasted it since I don't know if this may be relevant or not.
This is kernel_one code:
__global__ void kernel_one(int **d_numbers) {
int i = threadIdx.x + blockIdx.x * blockDim.x;
d_numbers[i] = (int *)malloc(L_CELLE*sizeof(int));
for(int j=0; j<L_CELLE;j++)
d_numbers[i][j] = 1;
}
And this is kernel_two code:
__global__ void kernel_two(int **d_numbers, int *d_result) {
int temp = 0;
for(int i=0; i<N_CELLE; i++) {
for(int j=0; j<L_CELLE;j++)
temp += d_numbers[i][j];
}
*d_result = temp;
}
Everything works fine (aka the count is correct) until I use less than 1024*2*512 total blocks in device memory. For example, if I #define N_CELLE 1024*4 the program starts giving "random" results, such as negative numbers.
Any idea of what the problem could be?
Thanks anyone!
In-kernel memory allocation draws memory from a statically allocated runtime heap. At larger sizes, you are exceeding the size of that heap and then your two kernels are attempting to read and write from uninitialised memory. This produces a runtime error on the device and renders the results invalid. You would already know this if you either added correct API error checking on the host side, or ran your code with the cuda-memcheck utility.
The solution is to ensure that the heap size is set to something appropriate before trying to run a kernel. Adding something like this:
size_t heapsize = sizeof(int) * size_t(N_CELLE) * size_t(2*L_CELLE);
cudaDeviceSetLimit(cudaLimitMallocHeapSize, heapsize);
to your host code before any other API calls, should solve the problem.
I don't know anything about CUDA but these are severe bugs:
You cannot convert from int** to void**. They are not compatible types. Casting doesn't solve the problem, but hides it.
&d_numbers gives the address of a pointer to pointer which is wrong. It is of type int***.
Both of the above bugs result in undefined behavior. If your program somehow seems to works in some condition, that's just by pure (bad) luck only.

Appending element into an array of strings in C

I have an array of strings with a given size, without using any memory allocation, how do I append something into it?
Say I run the code, its waiting for something you want to enter, you enter "bond", how do I append this into an array ? A[10] ?
If the array declared like
char A[10];
then you can assign string "bond" to it the following way
#include <string.h>
//...
strcpy( A, "bond" );
If you want to append the array with some other string then you can write
#include <string.h>
//...
strcpy( A, "bond" );
strcat( A, " john" );
You can't append to an array. When you define the array variable, C asks the is for enough contiguous memory. That's all the memory you ever get. You can modify the elements of the array (A[10]=5) but not the size.
However, you CAN create data structures that allow appending. The two most common are linked lists and dynamic arrays. Note, these are no built into the language. You have to implement them yourself or use a library. The lists and arrays of Python, Ruby and JavaScript are implemented as dynamic arrays.
LearnCThHardWay has a pretty good tutorial on linked lists, though the one on dynamic arrays is a little rough.
Hi,
It really depends on what you mean by append.
...
int tab[5]; // Your tab, with given size
// Fill the tab, however suits you.
// You then realize at some point you needed more room in the array
tab[6] = 5; // You CAN'T do that, obviously. Memory is not allocated.
The problem here can be two things :
Did you misjudge the size you need ? In that case, just make sure this given size you mentioned is correctly 'given', however that might be.
Or don't you know how much room you want at the beginning ? In that case, you''ll have to allocate the memory yourself ! There is no other way you can resize a memory chunk on the fly, if I might say.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define STR_MAX_SIZE 255 // Maximum size for a string. Completely arbitray.
char *new_string(char *str)
{
char *ret; // The future new string;
ret = (char *) malloc(sizeof(char) * 255); // Allocate the string
strcpy(ret, str); // Function from the C string.h standard library
return (ret);
}
int main()
{
char *strings[STR_MAX_SIZE]; // Your array
char in[255]; // The current buffer
int i = 0, j = 0; // iterators
while (in[0] != 'q')
{
printf("Hi ! Enter smth :\n");
scanf("%s", in);
strings[i] = new_string(in); // Creation of the new string, with call to malloc
i++;
}
for ( ; j < i ; j++)
{
printf("Tab[ %d ] :\t%s\n", j, strings[j]); // Display
free(strings[j]); // Memory released. Important, your program
// should free every bit it malloc's before exiting
}
return (0);
}
This is the easiest solution I could think of. It's probably not the best, but I just wanted to show you the whole process. I could have used the C standard library strdup(char *str) function to create a new string, and could have implemented my own quick list or array.
The size of an array variable cannot change. The only way to append to an array is to use memory allocation. You are looking for the realloc() function.
If you want to append a character or string to it;
strcpy(a, "james")
strcpy(a, "bond")

How do I declare an array of undefined or no initial size?

I know it could be done using malloc, but I do not know how to use it yet.
For example, I wanted the user to input several numbers using an infinite loop with a sentinel to put a stop into it (i.e. -1), but since I do not know yet how many he/she will input, I have to declare an array with no initial size, but I'm also aware that it won't work like this int arr[]; at compile time since it has to have a definite number of elements.
Declaring it with an exaggerated size like int arr[1000]; would work but it feels dumb (and waste memory since it would allocate that 1000 integer bytes into the memory) and I would like to know a more elegant way to do this.
This can be done by using a pointer, and allocating memory on the heap using malloc.
Note that there is no way to later ask how big that memory block is. You have to keep track of the array size yourself.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char** argv)
{
/* declare a pointer do an integer */
int *data;
/* we also have to keep track of how big our array is - I use 50 as an example*/
const int datacount = 50;
data = malloc(sizeof(int) * datacount); /* allocate memory for 50 int's */
if (!data) { /* If data == 0 after the call to malloc, allocation failed for some reason */
perror("Error allocating memory");
abort();
}
/* at this point, we know that data points to a valid block of memory.
Remember, however, that this memory is not initialized in any way -- it contains garbage.
Let's start by clearing it. */
memset(data, 0, sizeof(int)*datacount);
/* now our array contains all zeroes. */
data[0] = 1;
data[2] = 15;
data[49] = 66; /* the last element in our array, since we start counting from 0 */
/* Loop through the array, printing out the values (mostly zeroes, but even so) */
for(int i = 0; i < datacount; ++i) {
printf("Element %d: %d\n", i, data[i]);
}
}
That's it. What follows is a more involved explanation of why this works :)
I don't know how well you know C pointers, but array access in C (like array[2]) is actually a shorthand for accessing memory via a pointer. To access the memory pointed to by data, you write *data. This is known as dereferencing the pointer. Since data is of type int *, then *data is of type int. Now to an important piece of information: (data + 2) means "add the byte size of 2 ints to the adress pointed to by data".
An array in C is just a sequence of values in adjacent memory. array[1] is just next to array[0]. So when we allocate a big block of memory and want to use it as an array, we need an easy way of getting the direct adress to every element inside. Luckily, C lets us use the array notation on pointers as well. data[0] means the same thing as *(data+0), namely "access the memory pointed to by data". data[2] means *(data+2), and accesses the third int in the memory block.
The way it's often done is as follows:
allocate an array of some initial (fairly small) size;
read into this array, keeping track of how many elements you've read;
once the array is full, reallocate it, doubling the size and preserving (i.e. copying) the contents;
repeat until done.
I find that this pattern comes up pretty frequently.
What's interesting about this method is that it allows one to insert N elements into an empty array one-by-one in amortized O(N) time without knowing N in advance.
Modern C, aka C99, has variable length arrays, VLA. Unfortunately, not all compilers support this but if yours does this would be an alternative.
Try to implement dynamic data structure such as a linked list
Here's a sample program that reads stdin into a memory buffer that grows as needed. It's simple enough that it should give some insight in how you might handle this kind of thing. One thing that's would probably be done differently in a real program is how must the array grows in each allocation - I kept it small here to help keep things simpler if you wanted to step through in a debugger. A real program would probably use a much larger allocation increment (often, the allocation size is doubled, but if you're going to do that you should probably 'cap' the increment at some reasonable size - it might not make sense to double the allocation when you get into the hundreds of megabytes).
Also, I used indexed access to the buffer here as an example, but in a real program I probably wouldn't do that.
#include <stdlib.h>
#include <stdio.h>
void fatal_error(void);
int main( int argc, char** argv)
{
int buf_size = 0;
int buf_used = 0;
char* buf = NULL;
char* tmp = NULL;
char c;
int i = 0;
while ((c = getchar()) != EOF) {
if (buf_used == buf_size) {
//need more space in the array
buf_size += 20;
tmp = realloc(buf, buf_size); // get a new larger array
if (!tmp) fatal_error();
buf = tmp;
}
buf[buf_used] = c; // pointer can be indexed like an array
++buf_used;
}
puts("\n\n*** Dump of stdin ***\n");
for (i = 0; i < buf_used; ++i) {
putchar(buf[i]);
}
free(buf);
return 0;
}
void fatal_error(void)
{
fputs("fatal error - out of memory\n", stderr);
exit(1);
}
This example combined with examples in other answers should give you an idea of how this kind of thing is handled at a low level.
One way I can imagine is to use a linked list to implement such a scenario, if you need all the numbers entered before the user enters something which indicates the loop termination. (posting as the first option, because have never done this for user input, it just seemed to be interesting. Wasteful but artistic)
Another way is to do buffered input. Allocate a buffer, fill it, re-allocate, if the loop continues (not elegant, but the most rational for the given use-case).
I don't consider the described to be elegant though. Probably, I would change the use-case (the most rational).

Can you define the size of an array at runtime in C

New to C, thanks a lot for help.
Is it possible to define an array in C without either specifying its size or initializing it.
For example, can I prompt a user to enter numbers and store them in an int array ? I won't know how many numbers they will enter beforehand.
The only way I can think of now is to define a max size, which is not an ideal solution...
Well, you can dynamically allocate the size:
#include <stdio.h>
int main(int argc, char *argv[])
{
int *array;
int cnt;
int i;
/* In the real world, you should do a lot more error checking than this */
printf("enter the amount\n");
scanf("%d", &cnt);
array = malloc(cnt * sizeof(int));
/* do stuff with it */
for(i=0; i < cnt; i++)
array[i] = 10*i;
for(i=0; i < cnt; i++)
printf("array[%d] = %d\n", i, array[i]);
free(array);
return 0;
}
Perhaps something like this:
#include <stdio.h>
#include <stdlib.h>
/* An arbitrary starting size.
Should be close to what you expect to use, but not really that important */
#define INIT_ARRAY_SIZE 8
int array_size = INIT_ARRAY_SIZE;
int array_index = 0;
array = malloc(array_size * sizeof(int));
void array_push(int value) {
array[array_index] = value;
array_index++;
if(array_index >= array_size) {
array_size *= 2;
array = realloc(array, array_size * sizeof(int));
}
}
int main(int argc, char *argv[]) {
int shouldBreak = 0;
int val;
while (!shouldBreak) {
scanf("%d", &val);
shouldBreak = (val == 0);
array_push(val);
}
}
This will prompt for numbers and store them in a array, as you asked. It will terminated when passed given a 0.
You create an accessor function array_push for adding to your array, you call realloc from with this function when you run out space. You double the amount of allocated space each time. At most you'll allocate double the memory you need, at worst you will call realloc log n times, where is n is final intended array size.
You may also want to check for failure after calling malloc and realloc. I have not done this above.
Yes, absolutely. C99 introduced the VLA or Variable Length Array.
Some simple code would be like such:
#include <stdio.h>
int main (void) {
int arraysize;
printf("How bid do you want your array to be?\n");
scanf("%d",&arraysize);
int ar[arraysize];
return 0;
}
Arrays, by definition, are fixed-size memory structures. You want a vector. Since Standard C doesn't define vectors, you could try looking for a library, or hand-rolling your own.
You need to do dynamic allocation: You want a pointer to a memory address of yet-unkown size. Read up on malloc and realloc.
If all you need is a data structure where in you can change its size dynamically then the best option you can go for is a linked list. You can add data to the list dynamically allocating memory for it and this would be much easier!!
If you're a beginner, maybe you don't want to deal with malloc and free yet. So if you're using GCC, you can allocate variable size arrays on the stack, just specifying the size as an expression.
For example:
#include <stdio.h>
void dyn_array(const unsigned int n) {
int array[n];
int i;
for(i=0; i<n;i++) {
array[i]=i*i;
}
for(i=0; i<n;i++) {
printf("%d\n",array[i]);
}
}
int main(int argc, char **argv) {
dyn_array(argc);
return 0;
}
But keep in mind that this is a non standard extension, so you shouldn't count on it if portability matters.
You can use malloc to allocate memory dynamically (i.e. the size is not known until runtime).
C is a low level language: you have to manually free up the memory after it's used; if you don't, your program will suffer from memory leaks.
UPDATE
Just read your comment on another answer.
You're asking for an array with a dynamically-changing-size.
Well, C has no language/syntactic facilities to do that; you either have to implement this yourself or use a library that has already implemented it.
See this question: Is there an auto-resizing array/dynamic array implementation for C that comes with glibc?
For something like this, you might want to look into data structures such as:
Linked Lists (Ideal for this situation)
Various Trees (Binary Trees, Heaps, etc)
Stacks & Queues
But as for instantiating a variable sized array, this isn't really possible.
The closest to a dynamic array is by using malloc and it's associated commands (delete, realloc, etc).
But in this situation, using commands like malloc may result in the need to expand the array, an expensive operation where you initialize another array and then copy the old array into that. Lists, and other datatypes, are generally much better at resizing.
If you're looking for array facilities and don't want to roll your own, try the following:
Glib
Apache APR
NSPR
Above given answers are correct but there is one correction, the function malloc() reserve a block of memory of specified size and return a pointer of type void* which can be casted into pointer of any form.
Syntax: ptr = (cast-type*) malloc(byte-size)
#include<stdio.h>
#include<cstdlib>
int main(int argc,char* argv[]){
int *arraySize,length;
scanf("%d",&length);
arraySize = (int*)malloc(length*sizeof(int));
for(int i=0;i<length;i++)
arraySize[i] = i*2;
for(int i=0;i<length;i++)
printf("arrayAt[%d]=%d\n",i,arraySize[i]);
free(arraySize);
}

Resources