2009-08-25 40 views
10

Tôi có một mảng các giá trị tùy ý, vì vậy tôi đã định nghĩa nó như là một mảng của con trỏ void, vì vậy tôi có thể trỏ đến bất kỳ loại thông tin nào (như int, mảng ký tự, v.v.). Tuy nhiên, làm thế nào để tôi thực sự gán một int cho nó?Nếu tôi có một con trỏ void, làm thế nào để đặt một int vào nó?

Đưa ví dụ này khởi tạo:

void* data[10]; 
int x = 100; 

trực giác của tôi sẽ nghĩ này, nhưng điều này đưa ra một lỗi biên dịch:

data[0] = malloc(sizeof(int)); 
*(data[0]) = x; 

Ngoài ra tôi nghĩ về việc sử dụng &x, nhưng tôi sẽ lấy địa chỉ của một biến cục bộ, mà (theo sự hiểu biết của tôi) sẽ bị xóa sau khi thoát khỏi thủ tục. Vì vậy, nếu tôi có một biến địa phương x, làm thế nào tôi sẽ nhận được nó vào một loại con trỏ void của biến một cách chính xác?

Trả lời

24
*((int*)data[0])=x; 

sẽ làm điều đó.

Bạn có thể muốn xem xét sử dụng liên minh. Một cái gì đó như thế này:

union myvalues 
{ 
    int i; 
    double d; 
    long l; 
}; 

Sau đó, bạn có thể có

union myvalues *foo[10]; 
foo[0] = malloc(sizeof(union myvalues)); 
foo[0]->i = x; 

Bạn cũng có thể typedef công đoàn. sizeof(union myvalues) sẽ tối đa là sizeof thành viên. Vì vậy, nếu bạn có int i;char c[40] trong liên minh, sizeof(union myvalues) sẽ là 40. Viết tới i sau đó sẽ ghi đè 4 ký tự đầu tiên trong c (giả sử int của bạn là 4 byte).

+0

Hoặc chỉ đơn giản là sử dụng một loạt các công đoàn, và quên malloc –

+0

Thật vậy, điểm tốt. Tôi đã đi với gần nhất với bản gốc. –

+0

Cảm ơn nhưng điều này sẽ làm việc với con trỏ mảng ký tự cũng (char *).Và điều này sẽ không gây ra vấn đề liên kết trên một số nền tảng? Và cuối cùng, nếu tôi có một char [40] nó có vẻ như một sự lãng phí bộ nhớ để dự trữ 40 byte nếu tôi chỉ sẽ sử dụng 4. :-) – pbean

9
*((int *)data[0]) = x; 

Bản sao của x sẽ được thực hiện, vì vậy thực tế đó là biến cục bộ không quan trọng.

1

cho răng cưa lý do của nó tốt hơn để làm

mempcy(data[0], &x, sizeof(int)); 

Vì nó xảy ra trình biên dịch sẽ tối ưu hóa các cuộc gọi memcpy ra như sizeof (int) là một giá trị không đổi nhưng nó sẽ không phá vỡ quy tắc răng cưa khác nhau.

+0

quy tắc bí danh nào? –

+0

Tôi cho rằng Goz đang lo lắng về loại-punning, nhưng vì bạn không thể dereference 'void *', nó luôn luôn an toàn AFAIK để bí danh với một con trỏ 'void *'. Chỉ cần không dereference nó sau khi đúc cho bất cứ điều gì khác hơn là 'int *' hoặc 'char *'. –

2

Mặc dù bạn có thể sử dụng một dàn diễn viên để làm nhiệm vụ, nó có lẽ là sạch hơn nhiều để viết mã như:

 
void *data[ 10 ]; 
int x = 100; 
int *p; 

p = malloc(sizeof *p); 
data[ 0 ] = p; 
*p = x; 
+0

Tôi đồng ý với bạn cho ví dụ đơn giản này, và đó là phương pháp tôi đã đi đầu tiên. Tuy nhiên, vấn đề là có nhiều kiểu dữ liệu có thể khác nhau và như vậy, vì vậy tôi sẽ phải khai báo rất nhiều biến cục bộ tạm thời có thể hoặc không được sử dụng tại một lần thực hiện nhất định. – pbean

+0

+1 để sử dụng ít dấu chấm câu hơn – sigjuice

1

thử điều này:

data[0] = malloc(sizeof(int)); 
*((int*)data[0]) = x; 

hoặc

(int) (*(data[0])) = x; 

đừng quên

free (data[0]); 

sau đó.

Các vấn đề liên quan