Error void is not a pointer to object type

I have a C++ program: struct arguments { int a, b, c; arguments(): a(3), b(6), c(9) {} }; class test_class{ public: void *member_func(void *args){ arguments vars = (arguments *...

I have a C++ program:

struct arguments
{
  int a, b, c;  
  arguments(): a(3), b(6), c(9) {}
};

class test_class{
  public:

    void *member_func(void *args){
      arguments vars = (arguments *) (*args); //error: void is not a 
                                              //pointer-to-object type

      std::cout << "n" << vars.a << "t" << vars.b << "t" << vars.c << "n";
    }
};

On compile it throws an error:

error: ‘void*’ is not a pointer-to-object type

Can someone explain what I am doing wrong to produce this error?

Eric Leschinski's user avatar

asked Oct 31, 2011 at 3:30

Matt Munson's user avatar

8

You are dereferencing the void * before casting it to a concrete type. You need to do it the other way around:

arguments vars = *(arguments *) (args);

This order is important, because the compiler doesn’t know how to apply * to args (which is a void * and can’t be dereferenced). Your (arguments *) tells it what to do, but it’s too late, because the dereference has already occurred.

answered Oct 31, 2011 at 3:35

bdonlan's user avatar

bdonlanbdonlan

221k29 gold badges264 silver badges321 bronze badges

3

Bare bones example to reproduce the above error:

#include <iostream>
using namespace std;
int main() {
  int myint = 9;             //good
  void *pointer_to_void;     //good
  pointer_to_void = &myint;  //good

  cout << *pointer_to_void;  //error: 'void*' is not a pointer-to-object type
}

The above code is wrong because it is trying to dereference a pointer to a void. That’s not allowed.

Now run the next code below, If you understand why the following code runs and the above code does not, you will be better equipped to understand what is going on under the hood.

#include <iostream>
using namespace std;
int main() {
    int myint = 9;
    void *pointer_to_void;
    int *pointer_to_int; 
    pointer_to_void = &myint;
    pointer_to_int = (int *) pointer_to_void;

    cout << *pointer_to_int;   //prints '9'
    return 0;
}

answered May 27, 2014 at 1:38

Eric Leschinski's user avatar

Eric LeschinskiEric Leschinski

142k95 gold badges408 silver badges332 bronze badges

You have the * in the wrong place. So you’re trying dereference the void*.
Try this instead:

arguments vars = *(arguments *) (args);
std::cout << "n" << vars.a << "t" << vars.b << "t" << vars.c << "n";

Alternatively, you can do this: (which also avoids the copy-constructor — as mentioned in the comments)

arguments *vars = (arguments *) (args);
std::cout << "n" << vars->a << "t" << vars->b << "t" << vars->c << "n";

answered Oct 31, 2011 at 3:33

Mysticial's user avatar

MysticialMysticial

461k45 gold badges333 silver badges329 bronze badges

1

The problem as bdonlan said is «dereferencing void* before casting».

I think this example would help:

#include <iostream>

using namespace std;

int main()
{



   void *sad;
   int s = 23;
   float d = 5.8;

   sad = &s;
   cout << *(int*) sad;//outputs 23//wrong: cout << *sad ;//wrong: cout << (int*) *sad;



   sad = &d;
   cout << *(float *) sad;//outputs 5.8//wrong: cout << *sad ;//wrong: cout << (float*) *sad;

   return 0;
}

answered Jun 9, 2015 at 15:43

Cid's user avatar

CidCid

2,6565 gold badges28 silver badges39 bronze badges

*args means «the object(value) args points to». Therefore, it can not be casted as pointer to object(argument). That’s why it is giving error

answered Oct 31, 2011 at 4:57

user966379's user avatar

user966379user966379

2,7232 gold badges24 silver badges29 bronze badges

The problem above there is that you are trying to deference a void pointer which is not allowed in C or C++.

However, this still works:

#include <iostream>
using namespace std;
int main()
{
    int b=10;
    void *a=&b;
    int *ptr=(int*)a;
    cout<<*ptr;;
} 

We can deference int* pointers after casting void pointers to int* pointers.

answered Jun 21, 2019 at 13:23

Priyanshu Tiwari's user avatar

void *stackAddr[NUM_THREADS];

stackAddr[i] = malloc(STACKSIZE);

The compiler (g++ 4.4.3) complains where the malloc is called…

warning: pointer of type ‘void *’ used in arithmetic
error: ‘void*’ is not a pointer-to-object type

If you are interested in seeing the whole code, here it goes…

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS 4

void *stackAddr[NUM_THREADS];
pthread_t thread[NUM_THREADS];
pthread_attr_t attr;

void *BusyWork(void *t)
{
   int i;
   long tid;
   double result=0.0;
   tid = (long)t;

   printf("Thread %ld starting...n",tid);
   for ( i = 0; i < 1000; i++)
   {
      result = result + sin(i*tid) * tan(i*tid);
   }
   printf("Thread %ld done. Result = %en", tid, result);
   pthread_exit((void*) t);
}

void pthread_create_with_stack( pthread_t * pthread, void *(*start_routine) (void *), int tid )
{
    const size_t STACKSIZE = 0xC00000; //12582912
    void *stackAddr;
    int rc;
    size_t i;
    pthread_t thread;
    pid_t pid;

    stackAddr[tid] = malloc(STACKSIZE); // Error here!
    pthread_attr_setstack(&attr, stackAddr[tid], STACKSIZE);

    rc = pthread_create( pthread, &attr, start_routine, (void*)tid );
}

int main (int argc, char *argv[])
{
   int rc;
   long t;
   void *status;

   /* Initialize and set thread detached attribute */
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

   for(t=0; t<NUM_THREADS; t++) 
   {
      printf("Main: creating thread %ldn", t);
      rc = pthread_create_with_stack(&thread[t], BusyWork, t); 
      if (rc) 
      {
         printf("ERROR; return code from pthread_create() is %dn", rc);
         exit(-1);
      }
   }

   /* Free attribute and wait for the other threads */
   pthread_attr_destroy(&attr);
   for(t=0; t<NUM_THREADS; t++) 
   {
      rc = pthread_join(thread[t], &status);
      if (rc) 
      {
         printf("ERROR; return code from pthread_join() is %dn", rc);
         exit(-1);
      }
      printf("Main: completed join with thread %ld having a status"   
            "of %ldn",t,(long)status);
    }

    printf("Main: program completed. Exiting.n");
    pthread_exit(NULL);
}

Hello,

When compiling setconf (the shedskin branch) with shedskin 0.9.4 on 64-bit Arch Linux (gcc 5.3.0), I get the following warnings and errors:

% git checkout shedskin
Switched to branch 'shedskin'
% shedskin setconf.py
*** SHED SKIN Python-to-C++ Compiler 0.9.4 ***
Copyright 2005-2011 Mark Dufour; License GNU GPL version 3 (See LICENSE)

[analyzing types..]
********************************100%
[generating c++ code..]
*WARNING* 'list' instance containing function reference
*WARNING* setconf.py: '__iter' instance containing function reference
*WARNING* setconf.py: 'list' instance containing function reference
*WARNING* setconf.py:40: Function Decimal not called!
*WARNING* setconf.py:43: 'list' instance containing function reference
*WARNING* setconf.py:50: 'list' instance containing function reference
*WARNING* setconf.py:50: expression has no type
*WARNING* setconf.py:50: variable 'f' has no type
*WARNING* setconf.py:61: class 'str' has no method 'encode'
*WARNING* setconf.py:61: expression has no type
*WARNING* setconf.py:119: Function secondpart not called!
*WARNING* setconf.py:202: expression has no type
*WARNING* setconf.py:202: variable 'bytes' has no type
*WARNING* setconf.py:203: expression has no type
*WARNING* setconf.py:203: variable 'bytes' has no type
*WARNING* setconf.py:204: variable 'a' has no type
*WARNING* setconf.py:204: variable 'b' has no type
*WARNING* setconf.py:625: Function strip_trailing_zeros not called!
*WARNING* setconf.py:630: class 'str' has no method 'decode'
*WARNING* setconf.py:630: expression has no type
*WARNING* setconf.py:641: variable 'result' has no type
*WARNING* setconf.py:652: variable 'result' has no type
*WARNING* setconf.py:777: 'list' instance containing function reference
[elapsed time: 8.81 seconds]
...ckout/setconf% make

stdout from make:

g++  -O2 -march=native -Wno-deprecated  -I. -I/usr/lib/python2.7/site-packages/shedskin/lib /home/alexander/checkout/setconf/setconf.cpp /usr/lib/python2.7/site-packages/shedskin/lib/sys.cpp /usr/lib/python2.7/site-packages/shedskin/lib/stat.cpp /usr/lib/python2.7/site-packages/shedskin/lib/re.cpp /usr/lib/python2.7/site-packages/shedskin/lib/os/path.cpp /usr/lib/python2.7/site-packages/shedskin/lib/os/__init__.cpp /usr/lib/python2.7/site-packages/shedskin/lib/builtin.cpp -lgc -lpcre  -lutil -o setconf
Makefile:25: recipe for target 'setconf' failed

stderr from make:

/home/alexander/checkout/setconf/setconf.cpp: In function ‘void* __setconf__::__lambda0__()’:
/home/alexander/checkout/setconf/setconf.cpp:53:13: error: ‘void*’ is not a pointer-to-object type
     return f->close();
             ^
/home/alexander/checkout/setconf/setconf.cpp: In function ‘__shedskin__::str* __setconf__::bs(__shedskin__::str*)’:
/home/alexander/checkout/setconf/setconf.cpp:72:19: error: ‘class __shedskin__::str’ has no member named ‘encode’
         return x->encode();
                   ^
/home/alexander/checkout/setconf/setconf.cpp: In function ‘__shedskin__::__ss_bool __setconf__::test_change()’:
/home/alexander/checkout/setconf/setconf.cpp:234:14: error: ‘void*’ is not a pointer-to-object type
     a = bytes->join();
              ^
/home/alexander/checkout/setconf/setconf.cpp:235:14: error: ‘void*’ is not a pointer-to-object type
     b = bytes->join();
              ^
/home/alexander/checkout/setconf/setconf.cpp: In function ‘void* __setconf__::byte2decimal(__shedskin__::str*)’:
/home/alexander/checkout/setconf/setconf.cpp:677:23: error: ‘class __shedskin__::str’ has no member named ‘decode’
     return Decimal(b->decode());
                       ^
/home/alexander/checkout/setconf/setconf.cpp:677:31: error: ‘Decimal’ was not declared in this scope
     return Decimal(b->decode());
                               ^
/home/alexander/checkout/setconf/setconf.cpp: In function ‘__shedskin__::str* __setconf__::inc(__shedskin__::str*, __shedskin__::str*)’:
/home/alexander/checkout/setconf/setconf.cpp:688:53: error: ‘void*’ is not a pointer-to-object type
         result = bs(__str((byte2decimal(startvalue))->__add__(byte2decimal(s))));
                                                     ^
/home/alexander/checkout/setconf/setconf.cpp:692:39: error: ‘strip_trailing_zeros’ was not declared in this scope
     return strip_trailing_zeros(result);
                                       ^
/home/alexander/checkout/setconf/setconf.cpp: In function ‘__shedskin__::str* __setconf__::dec(__shedskin__::str*, __shedskin__::str*)’:
/home/alexander/checkout/setconf/setconf.cpp:703:53: error: ‘void*’ is not a pointer-to-object type
         result = bs(__str((byte2decimal(startvalue))->__sub__(byte2decimal(s))));
                                                     ^
/home/alexander/checkout/setconf/setconf.cpp:707:39: error: ‘strip_trailing_zeros’ was not declared in this scope
     return strip_trailing_zeros(result);
                                       ^
In file included from /home/alexander/checkout/setconf/setconf.cpp:1:0:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp: In instantiation of ‘__shedskin__::str* __shedskin__::repr(T) [with T = void* (*)()]’:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/list.hpp:339:24:   required from ‘__shedskin__::str* __shedskin__::list<T>::__repr__() [with T = void* (*)()]’
/home/alexander/checkout/setconf/setconf.cpp:1071:1:   required from here
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:1035:87: error: request for member ‘__repr__’ in ‘* t’, which is of non-class type ‘void*()’
 template<class T> str *repr(T t) { if (!t) return new str("None"); return t->__repr__(); }
                                                                                       ^
In file included from /usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:950:0,
                 from /home/alexander/checkout/setconf/setconf.cpp:1:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/compare.hpp: In instantiation of ‘__shedskin__::__ss_int __shedskin__::__cmp(T, T) [with T = void* (*)(); __shedskin__::__ss_int = int]’:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:1253:20:   required from ‘__shedskin__::__ss_int __shedskin__::pyseq<T>::__cmp__(__shedskin__::pyobj*) [with T = void* (*)(); __shedskin__::__ss_int = int]’
/home/alexander/checkout/setconf/setconf.cpp:1071:1:   required from here
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/compare.hpp:88:24: error: request for member ‘__cmp__’ in ‘* a’, which is of non-class type ‘void*()’
     return a->__cmp__(b);
                        ^
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/compare.hpp: In instantiation of ‘__shedskin__::__ss_bool __shedskin__::__eq(T, T) [with T = void* (*)()]’:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/list.hpp:91:16:   required from ‘__shedskin__::__ss_bool __shedskin__::list<T>::__eq__(__shedskin__::pyobj*) [with T = void* (*)()]’
/home/alexander/checkout/setconf/setconf.cpp:1071:1:   required from here
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/compare.hpp:6:67: error: request for member ‘__eq__’ in ‘* a’, which is of non-class type ‘void*()’
 template<class T> inline __ss_bool __eq(T a, T b) { return ((a&&b)?(a->__eq__(b)):__mbool(a==b)); }
                                                                   ^
In file included from /home/alexander/checkout/setconf/setconf.cpp:1:0:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp: In instantiation of ‘T __shedskin__::__deepcopy(T, __shedskin__::dict<void*, __shedskin__::pyobj*>*) [with T = void* (*)()]’:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/list.hpp:298:33:   required from ‘__shedskin__::list<T>* __shedskin__::list<T>::__deepcopy__(__shedskin__::dict<void*, __shedskin__::pyobj*>*) [with T = void* (*)()]’
/home/alexander/checkout/setconf/setconf.cpp:1071:1:   required from here
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:1180:30: error: invalid conversion from ‘void* (*)()’ to ‘void*’ [-fpermissive]
     T u = (T)(memo->get(t, 0));
                              ^
In file included from /usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:1211:0,
                 from /home/alexander/checkout/setconf/setconf.cpp:1:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin/dict.hpp:313:31: note:   initializing argument 1 of ‘V __shedskin__::dict<K, V>::get(K, V) [with K = void*; V = __shedskin__::pyobj*]’
 template <class K, class V> V dict<K,V>::get(K key, V d) {
                               ^
In file included from /home/alexander/checkout/setconf/setconf.cpp:1:0:
/usr/lib/python2.7/site-packages/shedskin/lib/builtin.hpp:1184:37: error: request for member ‘__deepcopy__’ in ‘* t’, which is of non-class type ‘void*()’
     return (T)(t->__deepcopy__(memo));
                                     ^
make: *** [setconf] Error 1

hi ,when im trying to insert key-value pair in map(key-char array field of a structure,value-entire structure)im having errors .

NDBAPI/TGBitsNdbApi.cpp: In function `int get_map(Ndb*, char*, char*, void*, void*)’:
NDBAPI/TGBitsNdbApi.cpp:154: error: request for member `Msisdn’ in `structPtr’, which is of non-class type `void*’
NDBAPI/TGBitsNdbApi.cpp:156: error: `void*’ is not a pointer-to-object type
NDBAPI/TGBitsNdbApi.cpp:156: error: request for member `Msisdn’ in `structPtr’, which is of non-class type `void*’
NDBAPI/TGBitsNdbApi.cpp:156: error: `make_pair’ was not declared in this scope
TGBitsNdbApi.cpp

#include "TGBitsNdbApi.h"
#include <map>
......
......
int get_map(Ndb * myNdb,char * tableName,char * field,void * structPtr,void *Map)
{
	const NdbDictionary::Dictionary* myDict= myNdb->getDictionary();
        const NdbDictionary::Table *myTable= myDict->getTable(tableName);
        if (myTable == NULL)
                APIERROR(myDict->getNdbError());
	 const NdbDictionary::Index *myIndex= myDict->getIndex("index1",tableName);
	if(myIndex == NULL)
	APIERROR(myDict->getNdbError());

	NdbTransaction *myTransaction= myNdb->startTransaction();
        if (myTransaction == NULL) APIERROR(myNdb->getNdbError());

        NdbIndexOperation *myIndexOp= myTransaction->getNdbIndexOperation(myIndex);
        if (myIndexOp == NULL) 
	{
			std::cout << myTransaction->getNdbError().message << std::endl;
			myNdb->closeTransaction(myTransaction);
			return -1;
	}

	if(myIndexOp->readTuple(NdbOperation::LM_Exclusive) != 0)
	{
			std::cout << myTransaction->getNdbError().message << std::endl;
			myNdb->closeTransaction(myTransaction);
			return -1;
	}
	else
	{
		if(strcmp(structPtr.Msisdn,field)==0)
		{
			Map->insert(make_pair(structPtr.Msisdn,structPtr));//im gettin error in this line
		}
        }
......
......

TGBitsNdbApi.h

#ifndef TGBITSNDBAPI_H_
#define TGBITSNDBAPI_H_
....
....
typedef pair<char *,void *>make_pair;
....
....

HomeNwList.cpp

int main(int argc, char** argv)
{
      .....
      .....
        HomeNwSt homeNwSt;
	map<char *,HomeNwSt> HomeMap;
	map<char *,HomeNwSt>::iterator it;
        int val=get_map(Ndb * myNdb,char * tableName,char * field,(void *)&homeNwSt ,(void*)&HomeMap)
	      if(val==-1)
              ........
              ........
	for( it = HomeNwList.begin(); it != HomeNwList.end(); it++)
	   {
		
		HomeNwSt obj = (*it).second;
                std::cout << "col 1: "<< obj.NwId << "t";
                std::cout << "col 2: "<< obj.Msisdn << "tn";
	   }
	return 0;
}

HomeNwList.h

#ifndef HOMENWLIST_H_
#define HOMENWLIST_H_

#include "./NDBAPI/TGBitsNdbApi.h"
#include<map>
#include<utility>
typedef struct _HomeNwSt
{
	char Msisdn[20];
	int   NwId;
}HomeNwSt;

//typedef pair<char *,void *>make_pair;
....
....
#endif

i do understand it is showing this error because im sending the entire structure,map as void * in get_map() function and im trying to insert char array field of structure.i did tried typecastin it into char * which im not sure whether it is correct,but it was not working.so anyone could help me in fixing this error and explain me,as im not good in pointers.
Also,i didnt get the last error ,as i declared the make_pair in correct scope and i also checked spelling.

thanks

I have the following code (live on Coliru):

// untouchable extern library .hpp  file

typedef union ExternLibraryUnion
{
    int a;
    float b;
}ExternLibraryUnion;

// my code

#include <iostream>

class Container{
    public:
    Container() : m_union(NULL) {};

    ~Container(){
        if(m_union){
            delete m_union;
        }
    }

    void init(){
        m_union = new ExternLibraryUnion();
    }

    ExternLibraryUnion* get_union(){
        return m_union;
    }

private:
    ExternLibraryUnion* m_union;
};


class Master{
    public:
    Master() : m_union(NULL) {
        m_container.init();    
    };

    ~Master(){
        if(m_union){
            delete static_cast<ExternLibraryUnion*>(m_union);
        }
    }

    void load(){

    }

    void set(int i){
        m_union = m_container.get_union();
        m_union->a = i;
    }

    void* get_union(){
        return m_union;
    }

private:
    void* m_union;
    Container m_container;
};

class Worker{
    public:
    Worker() : m_extern_library_union(NULL) {};

    ~Worker(){
        if (m_extern_library_union){
            delete m_extern_library_union;
        }
    }

    void load(Master& master){
        m_extern_library_union = reinterpret_cast<ExternLibraryUnion*>(master.get_union());
    }

    int get_int(){
        return m_extern_library_union->a;
    }


private:
    ExternLibraryUnion* m_extern_library_union;
};

int main()
{
    Master master;
    master.set(3);

    Worker worker;
    worker.load(master);

    std::cout << worker.get_int() << std::endl;
}

The code produces:

main.cpp: In member function 'void Master::set(int)':
main.cpp:55:16: error: 'void*' is not a pointer-to-object type
         m_union->a = i;
                ^~

In an extern library, a union ExternLibraryUnion is defined which I’m using inside my own code. My problem, which I can’t get my head around, is in the set method of class Master. The Master member void* m_union should point to the union stored inside the member Container m_container. As I’m setting the m_union = m_container.get_union() the compiler should be able to know that I’m getting a ExternLibraryUnion* back from the get_union() method call. So I don’t quite the error arising from the assignment m_union->a = i. Sure, a void* has no type, but I assigned it a pointer of the precise type ExternLibraryUnion.

Let’s also say I can not touch the Container m_container object directly. I need to make the assigned through the void* m_union pointer.

Any help is highly appreciated!

void *stackAddr[NUM_THREADS];

stackAddr[i] = malloc(STACKSIZE);

Компилятор (g ++ 4.4.3) жалуется, где вызывается malloc …

warning: pointer of type ‘void *’ used in arithmetic
error: ‘void*’ is not a pointer-to-object type

Если вам интересно увидеть весь код, вот оно …

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS 4

void *stackAddr[NUM_THREADS];
pthread_t thread[NUM_THREADS];
pthread_attr_t attr;

void *BusyWork(void *t)
{
   int i;
   long tid;
   double result=0.0;
   tid = (long)t;

   printf("Thread %ld starting...n",tid);
   for ( i = 0; i < 1000; i++)
   {
      result = result + sin(i*tid) * tan(i*tid);
   }
   printf("Thread %ld done. Result = %en", tid, result);
   pthread_exit((void*) t);
}

void pthread_create_with_stack( pthread_t * pthread, void *(*start_routine) (void *), int tid )
{
    const size_t STACKSIZE = 0xC00000; //12582912
    void *stackAddr;
    int rc;
    size_t i;
    pthread_t thread;
    pid_t pid;

    stackAddr[tid] = malloc(STACKSIZE); // Error here!
    pthread_attr_setstack(&attr, stackAddr[tid], STACKSIZE);

    rc = pthread_create( pthread, &attr, start_routine, (void*)tid );
}

int main (int argc, char *argv[])
{
   int rc;
   long t;
   void *status;

   /* Initialize and set thread detached attribute */
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

   for(t=0; t<NUM_THREADS; t++) 
   {
      printf("Main: creating thread %ldn", t);
      rc = pthread_create_with_stack(&thread[t], BusyWork, t); 
      if (rc) 
      {
         printf("ERROR; return code from pthread_create() is %dn", rc);
         exit(-1);
      }
   }

   /* Free attribute and wait for the other threads */
   pthread_attr_destroy(&attr);
   for(t=0; t<NUM_THREADS; t++) 
   {
      rc = pthread_join(thread[t], &status);
      if (rc) 
      {
         printf("ERROR; return code from pthread_join() is %dn", rc);
         exit(-1);
      }
      printf("Main: completed join with thread %ld having a status"   
            "of %ldn",t,(long)status);
    }

    printf("Main: program completed. Exiting.n");
    pthread_exit(NULL);
}

#c #c #linux #gcc #g

#c #c #linux #gcc #g

Вопрос:

 void *stackAddr[NUM_THREADS];

stackAddr[i] = malloc(STACKSIZE);
 

Компилятор (g 4.4.3) жалуется, где вызывается malloc …

 warning: pointer of type ‘void *’ used in arithmetic
error: ‘void*’ is not a pointer-to-object type
 

Если вам интересно увидеть весь код, вот он…

 #include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUM_THREADS 4

void *stackAddr[NUM_THREADS];
pthread_t thread[NUM_THREADS];
pthread_attr_t attr;

void *BusyWork(void *t)
{
   int i;
   long tid;
   double result=0.0;
   tid = (long)t;

   printf("Thread %ld starting...n",tid);
   for ( i = 0; i < 1000; i  )
   {
      result = result   sin(i*tid) * tan(i*tid);
   }
   printf("Thread %ld done. Result = %en", tid, result);
   pthread_exit((void*) t);
}

void pthread_create_with_stack( pthread_t * pthread, void *(*start_routine) (void *), int tid )
{
    const size_t STACKSIZE = 0xC00000; //12582912
    void *stackAddr;
    int rc;
    size_t i;
    pthread_t thread;
    pid_t pid;

    stackAddr[tid] = malloc(STACKSIZE); // Error here!
    pthread_attr_setstack(amp;attr, stackAddr[tid], STACKSIZE);

    rc = pthread_create( pthread, amp;attr, start_routine, (void*)tid );
}

int main (int argc, char *argv[])
{
   int rc;
   long t;
   void *status;

   /* Initialize and set thread detached attribute */
   pthread_attr_init(amp;attr);
   pthread_attr_setdetachstate(amp;attr, PTHREAD_CREATE_JOINABLE);

   for(t=0; t<NUM_THREADS; t  ) 
   {
      printf("Main: creating thread %ldn", t);
      rc = pthread_create_with_stack(amp;thread[t], BusyWork, t); 
      if (rc) 
      {
         printf("ERROR; return code from pthread_create() is %dn", rc);
         exit(-1);
      }
   }

   /* Free attribute and wait for the other threads */
   pthread_attr_destroy(amp;attr);
   for(t=0; t<NUM_THREADS; t  ) 
   {
      rc = pthread_join(thread[t], amp;status);
      if (rc) 
      {
         printf("ERROR; return code from pthread_join() is %dn", rc);
         exit(-1);
      }
      printf("Main: completed join with thread %ld having a status"   
            "of %ldn",t,(long)status);
    }

    printf("Main: program completed. Exiting.n");
    pthread_exit(NULL);
}
 

Комментарии:

1. Какая строка кода выдает эту ошибку? malloc Строка?

2. Покажите фактический код, здесь нет ошибки.

3. @trojanfoe, да, строка malloc.

4. @Daniel, зачем использовать char *, когда мне действительно требуется void * .

5. Ошибка не в этом коде. Делает ли реальный код что-то вроде попытки добавить смещение к результату malloc() ?

Ответ №1:

Вы объявляете локальную переменную void *stackAddr , которая затеняет глобальный stackAddr массив.

Более того, это не массив, и применение оператора [] подстрочного индекса пытается сместить и разыменовать void указатель, отсюда и ошибка компиляции.

Разыменование и арифметика указателей на указатели void не разрешены стандартом, поскольку sizeof(void) не определены.

Комментарии:

1. @MetallicPriest: Да, это так. pthread_create_with_stack имеет локальную переменную void *stackAddr .

2. Как вы «не делаете ничего подобного», когда на самом деле вы именно это и делаете?

3. А, понятно! Спасибо за ваши ответы! Kerrek SB, Blagvoest фактически изменил свой ответ. Я прокомментировал его предыдущий ответ.

Ответ №2:

Вы перепутали свое объявление:

 void *stackAddr;
 

должно быть:

 void *stackAddr[];
 

(Вам также может потребоваться установить размер массива.)

Затем вы пытаетесь сделать это:

 stackAddr[tid] = malloc(STACKSIZE);
 

Итак, вы обращаетесь к элементу массива a void* .

Комментарии:

1. @MetallicPriest: нет, это не так. По крайней мере, я знаю, кто делает эти замечательные -1-ы..

2. Присмотритесь повнимательнее к своей pthread_create_with_stack функции. [] В вашем объявлении отсутствует.

3. @yi_H, хахаха, извини, чувак, удалил мой комментарий и поддержал его. Mystical комментировал локальный stackAddr, в то время как я просматривал глобальный, который объявлен как массив. На самом деле проблема была локальной, которую необходимо устранить.

Ответ №3:

Теперь, когда вы опубликовали реальный код, я предполагаю, что ошибка заключается в pthread_create_with_stack том, что у вас есть локальная переменная void * stackAddr , которая скрывает глобальный массив.

Похоже, вам следует просто удалить локальную переменную.

Ответ №4:

То, что вы опубликовали первым, не является проблемой.

 void *stackAddr[NUM_THREADS];
 

Но в коде у вас есть что-то еще:

 void *stackAddr;
 

поэтому компилятор пытается использовать эту локальную переменную и, конечно же, не может скомпилироваться..

Ответ №5:

В pthread_create_with_stack , у вас есть этот код:

 void *stackAddr;
...
stackAddr[tid] = malloc(STACKSIZE)
 

Выражение stackAddr[tid] пытается выполнить арифметические вычисления для a void* .

Ответ №6:

В C указатели void не имеют атрибутов, включая size. В результате вы не можете вычислить адрес смещения для пустот i-числа с начала массива. Именно спецификация определенного индекса в массиве вызывает ваши математические проблемы.

Ответ №7:

В опубликованной вами версии stackAddr это не массив, которому вы присваиваете значение stackAddr[tid] . Компилятор заменяет это выражением в *(stackAddr tid) скобках , оценивающим значение to stackAddr tid * sizeof(void) , поэтому компилятор предупреждает вас об sizeof(void) этом .

Комментарии:

1. Компилятор знает размер и выравнивание всех полных типов, в том числе void* . Судя по именам переменных, OP нуждается в массиве для отслеживания количества блоков памяти, которые будут использоваться в качестве стеков потоков.

2. Все это четко указано стандартом: void* достаточно велико, чтобы содержать любой указатель на объект. Выравнивание не является частью языка. Вам нужны указатели void именно для результата вызовов malloc() or ::operator new() .

3. void * будет того же размера, что и, скажем, char * и выравнивание не имеет к этому никакого отношения. malloc() возвращает void * итак, в чем проблема? Я сам этого не вижу.

4. Хорошо, я постараюсь помнить об этом, хотя очень редко я имею дело с void * s напрямую. Спасибо за разъяснение. Я написал свой первоначальный комментарий как предположение о том, на что жаловался компилятор, прежде чем был опубликован новый код (с новым объявлением внутри функции). Я обновил свое предположение, чтобы просто объяснить предупреждение, но, конечно, другие ответы здесь действительно охватывают то, что не так.

Понравилась статья? Поделить с друзьями:
  • Error vocaloid lyrics
  • Error vmerror принтер
  • Error vixx скачать песню бесплатно
  • Error virustotal probably now is blocking our requests
  • Error virtualtablet hid driver is not connected