why can't I return local variable? - function

I don't know why c++'s rule says that I can't return local variable?
this simple "max" function totally has no problem;
int max(int a,int b)
{
int maxnum;
if(a>b)maxnum= a;
else maxnum= b;
return maxnum;
}
int main( int argc, char** argv )
{
cout<<max(10,30);
system("PAUSE");
return 0;
}
but, when I want to return local variable as before in opencv,it turns out wrong data
why can't I return local variable here?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
Mat GetIntensity(Mat *pic,int y,int x)
{
float Array[6];
for(int i=0;i<6;i++)
{
Array[i]=pic[i].at<uchar>(y,x);
}
Mat Intensity(6,1,CV_32FC1,&Array);
cout<<Intensity;
return Intensity;
}
int main( int argc, char** argv )
{
stringstream ss;
string pic_name;
Mat pic[6];
for(int i=0;i<6;i++)
{
ss.clear();
ss.str(std::string());
ss<<"pic"<<i<<".bmp"<<endl;
ss>>pic_name;
pic[i] = imread(pic_name, CV_LOAD_IMAGE_GRAYSCALE);
if(! pic[i].data )
{// Check for invalid input
cout << "Could not open or find the image" << endl ;
system("pause");
return -1;
}
//namedWindow( pic_name, CV_WINDOW_AUTOSIZE );
// Create a window for display.
//imshow(pic_name, pic[i] );
}
cout<<=GetIntensity(pic,60,60);
system("PAUSE");
//waitKey(0);
return 0;
}

your construct here uses a local array to hold the values. this will get invalid, once your Mat leaves the scope:
Mat GetIntensity(Mat *pic,int y,int x)
{
float Array[6]; //problem
for(int i=0;i<6;i++)
{
Array[i]=pic[i].at<uchar>(y,x);
}
Mat Intensity(6,1,CV_32FC1,&Array); // problem
cout<<Intensity;
return Intensity;
}
better create a Mat with it's own data:
Mat GetIntensity(Mat *pic,int y,int x)
{
Mat Intensity(6,1,CV_32FC1); // no problem
for(int i=0;i<6;i++)
{
Intensity.at<float>(i) = pic[i].at<uchar>(y,x);
}
cout<<Intensity;
return Intensity;
}

Related

RISC-V fuzzing emulation

I am new to this but I need to emulate RISC-V using qemu. As a start for my fuzzing project, how can I do give qemu an instruction set and get the changes in the registries as an output.
I probably understand your question. Because I don't have a riscv-related environment here, I can only provide a solution.
For example, in riscv, we design a function to get the values of all registers, relying on qemu's plugin module (such as qemu_plugin_register_vcpu_insn_exec_cb()).
plugin_test.c
#include <inttypes.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <glib.h>
#include <qemu-plugin.h>
QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
#define CPU_SIZE 32
static int cpu_num;
static int cpu_value[CPU_SIZE]={0};
static void vcpu_insn_exec_before(unsigned int cpu_index, void *)
{
for (size_t i = 0; i < cpu_num; i++)
{
/* code */
for (size_t j = 0; j < CPU_SIZE; i++)
{
if(cpu_value[j] != get_cpu_register(i,j)) {
// The value of cpu has changed
...
} else {
// The value of cpu has not changed
...
}
}
}
}
static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
{
size_t n = qemu_plugin_tb_n_insns(tb);
size_t i;
for (i = 0; i < n; i++) {
struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
qemu_plugin_register_vcpu_insn_exec_cb(
insn, vcpu_insn_exec_before, QEMU_PLUGIN_CB_NO_REGS,void *);
}
}
static void plugin_exit(qemu_plugin_id_t id, void *p)
{
}
QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
const qemu_info_t *info,
int argc, char **argv)
{
if(info->system_emulation) {
cpu_num = info->system.smp_vcpus;
} else {
cpu_num = 1;
}
qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans);
qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
return 0;
}
api-ext.c
void *qemu_get_cpu(int index);
static uint32_t get_cpu_register(unsigned int cpu_index, unsigned int reg) {
uint8_t* cpu = qemu_get_cpu(cpu_index);
return *(uint32_t*)(cpu + 33488 + 5424 + reg * 4);
}
It should be noted that the content in api-ext.c is obtained from others. This is the function used to obtain the value of arm cpu. You need to check the source code or documentation for riscv.

Functions returning pointers not printing correctly

When I run the program shown below, it prints the address correctly inside the function (fun), but outside the function is always prints zero
#include <stdio.h>
int *fun();
main()
{
int *p;
printf("\n %u", p);
p = fun();
printf("\n %u", fun());
}
int *fun()
{
int i = 20;
printf("\n %u", &i);
return (&i);
}

Using host class member pointing to device memory in device code

I want to have an instance of a Container class allocating some device and host memory on initialization. I want to use the allocated memory in device code, without passing the actual pointer (for API reasons).
How do I create a global __device__ pointer to the member pointing to the device memory? I am happy to use thrust if that helps.
Here is a small example:
#include <iostream>
struct Container {
int *h_int = (int*)malloc(4*sizeof(int));
int *d_int;
Container() {
h_int[0] = 6; h_int[1] = 6; h_int[2] = 6; h_int[3] = 6;
cudaMalloc(&d_int, 4*sizeof(int));
memcpyHostToDevice();
}
void memcpyHostToDevice() {
cudaMemcpy(d_int, h_int, 4*sizeof(int), cudaMemcpyHostToDevice);
}
void memcpyDeviceToHost() {
cudaMemcpy(h_int, d_int, 4*sizeof(int), cudaMemcpyDeviceToHost);
}
};
Container stuff;
__device__ auto d_int = &stuff.d_int; // How do I get that right?
__global__ void edit() { // To keep the API simple I do not want to pass the pointer
auto i = blockIdx.x*blockDim.x + threadIdx.x;
d_int[i] = 1 + 2*(i > 0) + 4*(i > 2);
}
int main(int argc, char const *argv[]) {
edit<<<4, 1>>>();
stuff.memcpyDeviceToHost();
std::cout << stuff.h_int[0] << stuff.h_int[1] << stuff.h_int[2] << stuff.h_int[3] << "\n";
return 0;
}
There are two problems here:
You can't statically inititalize a __device__ variable in the way you are trying to (and the value you are trying to apply isn't correct either). The CUDA runtime API contains a function for initialising global scope device symbols. Use that instead.
Your global scope declaration of stuff shouldn't work either for a number of subtle reasons discussed here (it is technically undefined behaviour). Declare it at main scope instead.
Putting these two things together should lead your to do something like this instead:
__device__ int* d_int;
// ...
int main(int argc, char const *argv[]) {
Container stuff;
cudaMemcpyToSymbol(d_int, &stuff.dint, sizeof(int*));
edit<<<4, 1>>>();
// ...
Here is a fully worked example:
$ cat t1199.cu
#include <iostream>
struct Container {
int *h_int = (int*)malloc(4*sizeof(int));
int *d_int;
Container() {
h_int[0] = 6; h_int[1] = 6; h_int[2] = 6; h_int[3] = 6;
cudaMalloc(&d_int, 4*sizeof(int));
memcpyHostToDevice();
}
void memcpyHostToDevice() {
cudaMemcpy(d_int, h_int, 4*sizeof(int), cudaMemcpyHostToDevice);
}
void memcpyDeviceToHost() {
cudaMemcpy(h_int, d_int, 4*sizeof(int), cudaMemcpyDeviceToHost);
}
};
//Container stuff;
__device__ int *d_int; // = &stuff.d_int; // How do I get that right?
__global__ void edit() { // To keep the API simple I do not want to pass the pointer
auto i = blockIdx.x*blockDim.x + threadIdx.x;
d_int[i] = 1 + 2*(i > 0) + 4*(i > 2);
}
int main(int argc, char const *argv[]) {
Container stuff;
cudaMemcpyToSymbol(d_int, &stuff.d_int, sizeof(int *));
edit<<<4, 1>>>();
stuff.memcpyDeviceToHost();
std::cout << stuff.h_int[0] << stuff.h_int[1] << stuff.h_int[2] << stuff.h_int[3] << "\n";
return 0;
}
$ nvcc -std=c++11 -o t1199 t1199.cu
$ cuda-memcheck ./t1199
========= CUDA-MEMCHECK
1337
========= ERROR SUMMARY: 0 errors
$

In C programming how to use the value of an array outside the function where the value of the array is assigned?

In my program I used a function called
void printBoard(char board[26][26], int n);
This is my actual coding:
#include <stdio.h>
#include <stdlib.h>
void printBoard(char board[26][26], int n);
int main(void) {
//variable 'n' determines board dimension
int n;
printf("Enter the board dimension: ");
scanf("%d",&n);
char board[n][n];
printBoard(board, n);
printf("\n\n");
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
return (EXIT_SUCCESS);
}
void printBoard(char board[26][26], int n){
printf(" ");
for(int i=0;i<n;i++){
printf("%c",97+i);
}
printf("\n");
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]='U';
}
}
board[(n/2)-1][(n/2)-1]='W';
board[n/2][n/2]='W';
board[(n/2)-1][n/2]='B';
board[n/2][(n/2)-1]='B';
for(int i=0;i<n;i++){
printf("%c ",97+i);
for(int j=0;j<n;j++){
printf("%c",board[i][j]);
}
printf("\n");
}
}
The value of the array 'board[26][]26' gets assigned inside the function 'printBoard'. So the value gets lost once I am outside of the scope of this function. But I need to use the value of this array outside of this function. How can I do that?
Thank you
You're not passing the array into printBoard by value, you're just passing a pointer. The changes in the function will persist beyond the function because you're modifying the same memory, not a copy. If you're seeing unexpected output, it's not because of a scope issue with changes made by printBoard.

thrust::device_reference can't be used with printf?

I am using the thrust partition function to partition array into even and odd numbers. However, when i try to display the device vector, it shows random values. Please let me know where is the error. I think i have done everything correct.
#include<stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include<thrust/partition.h>
struct is_even
{
//const int toCom;
//is_even(int val):toCom(val){}
__device__
bool operator()(const int &x)
{
return x%2;
}
};
void main(){
thrust::host_vector<int> H(6);
for(int i =0 ; i<H.size();i++){
H[i] = i+1;
}
thrust::device_vector<int> D = H;
thrust::partition(D.begin(),D.end(),is_even());
for(int i =0 ;i< D.size();i++){
printf("%d,",D[i]);
}
getchar();
}
You can't send a thrust::device_reference (i.e., the result of D[i]) through printf's ellipsis because it is not a POD type. See the documentation. Your code will produce a compiler warning to this effect.
Cast to int first:
for(int i = 0; i < D.size(); ++i)
{
printf("%d,", (int) D[i]);
}