Im a beginner in C,In the following code what can be the output value of &str and str when it is cast as an integer.??
int main()
{
char *str;
/* Initial memory allocation */
str = (char *) malloc(15);
strcpy(str, "Hello");
printf("String = %s, Address = %d ,val=%d\n", str, &str,str);
free(str);
return(0);
}
This is the output i got:
String = Hello, Address = -1407247144 ,val=22335504
Related
I'd like to declare the array of below structure,
typedef struct {
std::string key;
union {
bool b;
int i;
double d;
std::string s;
} val;
} ttt;
and initialize the arrat with C99 type, designated way.
ttt a[] = {
{
.key = std::string("key a"),
.val .. ???
How..?
Thank you!
I'm trying to find the Rust equivalent of having a ASCII string buffer on the stack to have the same efficiency as plain C code has.
Here an example on what I mean with a simplified toy exercise:
the goal is to generate a random-content and random-length ASCII string that is at most 50 characters long. Thus I keep a char buffer on the stack that is used to iteratively construct the string. Once finished, the string is copied onto the heap with the just-right malloc size and returned to the user.
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#define ASCII_PRINTABLE_FIRST ' '
#define ASCII_PRINTABLE_AMOUNT 95
#define MAX_LEN 50
#define MAX_LEN_WITH_TERM (MAX_LEN + 1)
char* generate_string(void) {
char buffer[MAX_LEN_WITH_TERM];
srand((unsigned) time(NULL));
// Generate random string length
const int len = rand() % MAX_LEN_WITH_TERM;
int i;
for (i = 0; i < len; i++) {
// Fill with random ASCII printable character
buffer[i] = (char)
((rand() % ASCII_PRINTABLE_AMOUNT) + ASCII_PRINTABLE_FIRST);
}
buffer[i] = '\0';
return strdup(buffer);
}
int main(void) {
printf("Generated string: %s\n", generate_string());
return 0;
}
What I explored so far:
Using a buffer String::with_capacity(50) or BytesMut, but that allocates the buffer on the heap, which I would like to avoid. Sure, it's premature optimisation, but as an optimisation exercise let's image me calling generate_string() a billion times. That is a billion malloc calls to allocate the buffer. I don't want to use static memory.
Using a an array of chars on the stack, but it consumes 4x the space for just ASCII characters
What are your suggestions?
EDIT:
Yes, it leaks memory. That't not the point of my question, unless you want much longer snippets of code.
Yes, it has insecure random characters. That's not the point of my question.
Why would I allocate the buffer on the heap once per generate_string() call? To make the function self contained, stateless and without static memory. It does not require a pre-allocated buffer externally.
You can generate a random length u8 array (stored on the stack) and only allocate memory on the heap when you convert it to a String using the from_utf8 method. Example:
use rand::prelude::*;
const MAX_LEN: usize = 50;
const ASCII_START: u8 = 32;
const ASCII_END: u8 = 127;
fn generate_string() -> String {
let mut buffer = [0; MAX_LEN];
let mut rng = rand::thread_rng();
let buffer_len = rng.gen_range(0, MAX_LEN);
for i in 0..buffer_len {
buffer[i] = rng.gen_range(ASCII_START, ASCII_END);
}
String::from_utf8((&buffer[0..buffer_len]).to_vec()).unwrap()
}
fn main() {
for _ in 0..5 {
dbg!(generate_string());
}
}
playground
The Rust type that is equivalent to C's char is u8, so the equivalent to a char buffer on the stack is an u8 array.
let mut buf = [0u8; 20];
for i in 0..20 {
buf[i] = b'a' + i as u8;
}
To obtain a &str slice that points into the stack buffer, you can use std::str::from_utf8, which performs a UTF-8 check and returns the pointer if it is valid UTF-8.
fn takes_a_string(a: &str) {
println!("{}", a);
}
fn main() {
let mut buf = [0u8; 20];
for i in 0..20 {
buf[i] = b'a' + i as u8;
}
// This calls takes_a_string with a reference to the stack buffer.
takes_a_string(std::str::from_utf8(&buf).unwrap());
}
abcdefghijklmnopqrst
I am trying to compile this code:
#include <sys/types.h>
#include <argp.h>
#include <stdlib.h>
#include <xmmintrin.h>
__attribute__((noinline)) void vadd(float *a, float *b, size_t size)
{
size_t i;
for (i=0; i<size; i+=4)
{
__m128 v1 = _mm_load_ps(a + i); //loads up 4 floats into a __m128
__m128 v2 = _mm_load_ps(b + i); //loads up 4 floats into a __m128
__m128 v3 = _mm_add_ps(v1, v2);
_mm_store_ps(a+i, v3);
}
}
__attribute__((noinline)) void sadd(float *a, float *b, size_t size)
{
size_t i;
for(i=0; i<size; i++)
{
a[i] += b[i];
}
}
int main (void)
{
size_t size = 300000000;
float *a = (float *)calloc(size, sizeof(float));
float *b = (float *)calloc(size, sizeof(float));
vadd(a, b, size);
sadd(a, b, size);
}
I am receiving this error:
/usr/lib/gcc/i486-linux-gnu/4.8/include/mmintrin.h: In function ‘_mm_cvtsi32_si64’:
/usr/lib/gcc/i486-linux-gnu/4.8/include/mmintrin.h:61:3: error: can’t convert between vector values of different size
return (__m64) __builtin_ia32_vec_init_v2si (__i, 0);
Is there a way to work that out?
How can I initialize struct sockaddr_in globally. Third variable IN_ADDR sin_addr is a nested structure.
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
IN_ADDR sin_addr;
char sin_zero[8];
} addr;
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
};
Point 1
You cannot initalize struct sockaddr_in itself. You need to have a variable of this type, i.e, addr (as in your case) which you can initialize.
Point 2
You can use an inilitalizer list in brace-enclosed form to initialize the global variable. Also, you can make use of the .identifier option to initalize a member explicitly.
Assuming IN_ADDR is defined as
typedef struct sockaddr_in IN_ADDR;
you can write something like
struct sockaddr_in{
short sin_family;
unsigned short sin_port;
IN_ADDR sin_addr;
char sin_zero[8];
} addr = {AF_INET, 2015, .sin_addr.S_un.S_addr = 1234567890, .sin_zero = {1,2,3,4,5,6,7}};
to initilialize addr.
Here, the .sin_addr.S_un.S_addr is used to denote to the particular variable to be initializeed.
Using your structure/union definition ... here is a sample program ...
#include <stdio.h>
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned long u_long;
typedef struct in_addr
{
union
{
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
}S_un;
}IN_ADDR;
IN_ADDR u = // ====> Either do something like this ...
{
.S_un.S_un_b = {'a', 'b', 'c', 'd'}
//.S_un.S_un_w = {1, 2},
//.S_un.S_addr = 121212
};
struct sockaddr_in
{
short sin_family;
unsigned short sin_port;
IN_ADDR sin_addr;
char sin_zero[8];
}addr = { // ==============> Or do something like this.
10,
20,
.sin_addr.S_un.S_addr=12345,
"SOCKET"
};
int main()
{
printf("sin_family = %d\n", addr.sin_family);
printf("sin_port = %d\n", addr.sin_port);
printf("sin_addr.S_un.S_addr = %ld\n", addr.sin_addr.S_un.S_addr);
printf("sin_zero = %s\n", addr.sin_zero);
printf("%c %c %c %c\n", u.S_un.S_un_b.s_b1, u.S_un.S_un_b.s_b2, u.S_un.S_un_b.s_b3, u.S_un.S_un_b.s_b4);
//printf("%d %d\n", u.S_un.S_un_w.s_w1, u.S_un.S_un_w.s_w2);
//printf("%ld\n", u.S_un.S_addr);
return 0;
}
I wanted to create a quick quadtree in c++ but found that when I change a value of a struct within a function the value reverts. Also within the recursive function I wont some of the data created to be global. How do I do this?
#include <iostream>
struct a{
unsigned int value;
struct a * leaf[4];
};
void build(struct a root, unsigned int depth){
depth++;
root.value = 0;
struct a leaf0;
root.leaf[0] = &leaf0;
struct a leaf1;
root.leaf[1] = &leaf1;
struct a leaf2;
root.leaf[2] = &leaf2;
struct a leaf3;
root.leaf[3] = &leaf3;
if (depth != 5) {
build(*root.leaf[0], depth);
build(*root.leaf[1], depth);
build(*root.leaf[2], depth);
build(*root.leaf[3], depth);
}
}
int main(int argc, const char * argv[])
{
struct a root;
root.value = 364;
build(root, 0);
std::cout << root.value;
return 0;
}
You must pass the address of the struct to your function (which should accept a pointer to the struct):
void build(struct a *root, unsigned int depth) {
...
}
int main(int argc, const char * argv[])
...
build(&root, 0);
}