This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 2 years ago.
I'm using Swift and should I use C source with Bridging-Header.
C source has like this function.
char* testFunc2(char *input) { // input = [4, 5, 6, 7, 8, 9]
char v1[17] = { 0, };
memcpy(v1, input, 4);
return (char*)v1;
}
The v1's value will be [4, 5, 6, 7, 0, 0, 0...]
And I input data like this
var i1: [Int8] = [4, 5, 6, 7, 8, 9]
let idPtr = UnsafeMutablePointer<Int8>.allocate(capacity: 7)
idPtr.initialize(from: &i1, count: 6)
let tf2 = testFunc2(idPtr)
The address value is equal (char*)v1 with tf2.
But when I converted tf2(UnsafeMutablePointer) to Array,
the value is different.
I converted like this
let tt2Buf = UnsafeMutableBufferPointer(start: tt2, count: 17)
let tt2Arr = Array(tt2Buf)
When I return input(parameter) directly, converted value is right.
But when I did somegthing in C source and returned value,
the converted value is not correct with return value in C source.
I wasted day about 10 days with this problem....
How can I Do.....?
char v1[17] is local array, its scope is limited to testFunc2 function.
You cannot use its reference outside the function.
Maybe you can allocate memory dynamically and pass its reference.
char* testFunc2(char *input) { // input = [4, 5, 6, 7, 8, 9]
char *v1 = malloc(17);
memset(v1, 0, 17);
memcpy(v1, input, 4);
return v1;
}
However you have to free the memory at some point otherwise you will have memory leaks.
Related
This question is analogical to
Parallel write to array with an indices array
except that I guarantee the indices to be unique.
let indices = [1, 4, 7, 8];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
indices.iter_par().for_each(|x| {
arr[x] = some_function(x);
});
Is there a way to achieve this in Rayon? Perhaps I should somehow use unsafe, because obviously borrow checker can't verify uniqueness of indices.
You can certainly do it with unsafe, for example by sending a pointer to the threads:
// thin wrapper over pointer to make it Send/Sync
#[derive(Copy, Clone)]
struct Pointer(*mut u32);
unsafe impl Send for Pointer {}
unsafe impl Sync for Pointer {}
let indices = [1, 4, 7, 8];
let mut arr = [1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arr_ptr = Pointer(arr.as_mut_ptr());
indices.into_par_iter().for_each(move |x| {
// safety:
// * `indices` must be unique and point inside `arr`
// * `place` must not leak outside the closure
// * no element of `array` that is in `indices` may be accessed by
// some other thread while this is running
let place = unsafe { &mut *{arr_ptr}.0.add(x) };
*place = some_function(x);
});
But I'd reserve that kind of thing to use only as last resort. Once you introduce ad-hoc unsafe like this in your code base, you never know when you'll make a misstep and make your program vulnerable to random crashes and corruptions.
How do I use a for loop to add array 1 to array 2 and become the expected array like the example below?
What I expect is adding the first element in array 1 to array 2's second 1234 and continue adding up:
Array 1 = [4, 8]
Array 2 = [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
Expected Array:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
I am thinking of something like this, but just feel very strange.
N=4
for (int i=N; i<array.size; i++)
{
array2[i] = array1[...];
}
I guess your question is when
int array1[] = {4, 8};
int array2[] = {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4};
int arrayAnswer[] = {array2[0],array2[1],array2[2],array2[3],
array2[0]+array1[1],array2[1]+array1[1],array2[2]+array1[1],array2[3]+array1[1],
array2[0]+array1[2],array2[1]+array1[2],array2[2]+array1[2],array2[3]+array1[2]}
is it right? if so, please leave the comment and I will edit more
First of all, the question you made is not a good question. Please try to give more detailed information about your problem next time.
Answer for your question is, skip fist four member of array and add array1[1] on from array2[4] to array [7], and add array1[2] on from array2[8] to array [11]. You are going to need two loop. such as
for (i = 0; i < 2; i++){
for (j = 0; j < 4; j++){
//your function
}
}
I am not going to give you direct answer for the problem so that you can design your own. However, if your first array is {0, 4, 8}, your coding is going to be much easier. ty
As I know to get Stream from 2 dimensional array but I want to know how I can get Stream from below 3 dimensional array?
int[][][] data = {
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
},
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
};
If you can do it with a two-dimensional array then doing it for N dimensional array is not that difficult.
The solution can be done as follows:
IntStream result = Arrays.stream(data)
.flatMap(Arrays::stream)
.flatMapToInt(Arrays::stream);
To better help understand what is going on above, you can split the method invocations as follows:
// the call to Arrays.stream yields a Stream<int[][]>
Stream<int[][]> result1 = Arrays.stream(data);
// the call to flatMap yields a Stream<int[]>
Stream<int[]> result2 = result1.flatMap(Arrays::stream);
// the call to flatMapToInt yields a IntStream
IntStream intStream = result2.flatMapToInt(Arrays::stream);
You just need to call flatMap another time to change the stream from int[][] to stream of int[].
IntStream stream = Arrays.stream(data)
.flatMap(twoDArray -> Arrays.stream(twoDArray))
.flatMapToInt(oneDArray -> Arrays.stream(oneDArray));
Say I declared an array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}. Later I want it to be array[8] = {2, 3, 4, 5, 6, 7, 8, 9}.
Dismiss the first 2 elements. So it would start on array[2]. Reallocing array to array[2].
I tried:
int *array=(int*)malloc(10*sizeof(int));
...//do stuffs
array=(int*)realloc(array[2],8*sizeof(int));
It didn't work. Neither using &array[2], *array[2], nor creating an auxiliary array, reallocing Array to AuxArr than free(AuxArr).
Can I get a light?
You can only realloc a pointer to a memory block that has already been alloc'ed. So you can realloc(array), but not array[2] since that is a pointer to a location in the middle of a memory block.
You may want to try memmove instead.
Edit:In response to ThingyWotsit's comment, after memomving the data you want to the front of the array, then you can realloc to drop off the tail end.
Just use array += 2 or array = &array[2]. You can't realloc() it.
As I have found it very difficult to manipulate 2 dimensional arrays in C, I've decided to try and write a function that will take my 2D array and convert it to a 1D array. For the 2D array below I'd like it to translate to some thing like 1D_array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }.
I came across a very similar question on stack exchange, linked below, and have used the suggested code.
Convert 2D array to single array
The code I'm using is:
#define KP_ROWS 4
#define KP_COLS 4
static Uint16 KP_TEST_Keys[KP_ROWS][KP_COLS] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
void main()
{
Uint16 array1D[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
memcpy(array1D, KP_TEST_Keys, sizeof(Uint16) * KP_ROWS * KP_COLS);
}
Again my overall goal is to convert the 2D array to a 1D array.
EDIT: After clearing errors from before I have edited and just now tested the above code and it works! array1D contains the data in the format I wanted.
Am I using memcpy correctly?
OK, but prone to failure as the size of array1D is not certainly tied to the size of KP_TEST_Keys.
Uint16 array1D[KP_ROWS*KP_COLS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
// Recommend size of destination, not size of source
// Ideally, it would be the minimum of the size of source and destination.
memcpy(array1D, KP_TEST_Keys, sizeof array1D);
As #Kurokawa Masato commented, memcpy() must be used in a function.
Suggest using standard types like uint16_t rather than Uint16.
The 2D array data is already stored contiguously in the order you require of your 1D array; there is no need at all to duplicate the data in a separate array; you only need cast the 2D array as follows:
Uint16* array1D = (Uint16*)KP_TEST_Keys ;
This provides a 1D array view of the 2D array without copying the data. Changes to the 1D view change the 2D data directly so there is no need to copy to and from the two representations.
If the 1D array view is to be read-only you can enforce that by:
const Uint16* array1D = (const Uint16*)KP_TEST_Keys ;
Further if the 1D array is to be locked to the 2D array and not to be capable of reassignment to some other array then:
Uint16* const array1D = (Uint16* const)KP_TEST_Keys ;
or both combined ( a constant pointer to constant data):
const Uint16* const array1D = (const Uint16* const)KP_TEST_Keys ;
One significant difference here is that sizeof(array1D) is the size of the pointer, not the size of the array; you should use sizeof(KP_TEST_Keys) for both.
If either if these declarations is made at file scope after the declaration of KP_TEST_Keys, the 1D view will exist with the same lifetime and scope as the 2D:
static Uint16 KP_TEST_Keys[KP_ROWS][KP_COLS] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
static Uint16* array1D = (Uint16*)KP_TEST_Keys ;
You can also perform the cast directly at point of use rather then introducing a new variable to access individual elements such as:
Uint16 element = ((Uint16*)KP_TEST_Keys)[i] ;
where i is the 1D index 0 to sizeof(KP_TEST_Keys) - 1.