2 votes

Quelle est la différence entre 'ptr = &array[index]' et '*ptr = array[index]' ?

Je suis novice en programmation C et j'ai du mal à différencier cette syntaxe

ptr = &array[index]

contre celui-ci

*ptr = array[index]

Dans une fonction d'exemple que je vaux

void getDevice(Device* device)

la ligne fonctionne exactement comme je l'attends

*device = devices[index];

(le pointeur de périphérique déréférencé a maintenant une valeur devices[index] )

mais cette ligne provoque une défaillance

device = &devices[index];

(le pointeur du dispositif a devices[index] l'adresse de l'entreprise)

Je pense que les deux devraient finalement avoir le même effet ( ptr pointant vers devices[index] ). Qu'est-ce que je rate ici ?


Code réel :

void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{

  uint32_t physicalDeviceCount = 0;

  vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, VK_NULL_HANDLE);

  VkPhysicalDevice physicalDevices[physicalDeviceCount];

  vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, physicalDevices);

  int bestSuitedPhysicalDeviceLocation = 0;

  gPhysicalDevice  = &physicalDevices[bestSuitedPhysicalDeviceLocation]; // Causes segfault

  *gPhysicalDevice = physicalDevices[bestSuitedPhysicalDeviceLocation]; // Works
}

VkInstance

VkPhysicalDevice

vkEnumeratePhysicalDevices

1voto

Eric Postpischil Points 36641

ptr = &array[index] fixe ptr pour pointer vers array[index] . C'est-à-dire qu'il met l'adresse de array[index] en ptr .

*ptr = array[index] fixe *ptr à la valeur array[index] . C'est-à-dire qu'il récupère la valeur stockée dans array[index] et place cette valeur à l'endroit indiqué par ptr . Il ne change pas ptr .

La cause du défaut de segment que vous signalez ne peut pas être déterminée car vous n'avez pas fourni suffisamment de code ou d'informations. La ligne device = &devices[index]; en soi n'est probablement pas la cause.

1voto

G. Sliepen Points 2379

En supposant que vous appelez votre fonction comme ça :

vkInstance instance;
vkPhysicalDevice physicalDevice;

vkCreateInstance(..., &instance);
populatePhysicalDevice(&instance, &physicalDevice);

Ainsi, les deux valeurs des deux arguments passés sont les pointeurs vers instance y physicalDevice dans la portée de l'appelant. Les pointeurs (mais pas les valeurs qu'ils désignent) obtiennent copié dans les variables correspondantes dans populatePhysicalDevice :

void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{

Donc à ce stade, à l'intérieur populatePhysicalDevice() vous avez deux pointeurs que vous pouvez modifier à volonté, mais qui ne changeront rien dans la portée de l'appelant. Continuons :

  uint32_t physicalDeviceCount = 0;
  vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, VK_NULL_HANDLE);
  VkPhysicalDevice physicalDevices[physicalDeviceCount];
  vkEnumeratePhysicalDevices(*gInstance, &physicalDeviceCount, physicalDevices);

Maintenant vous avez un tableau local de VKPhysicalDevice qui a été remplacée par vkEnumeratePhysicalDevices() . Vous voulez maintenant vous assurer que l'appelant reçoit une copie du dispositif physique le mieux adapté :

  int bestSuitedPhysicalDeviceLocation = 0;

  gPhysicalDevice  = &physicalDevices[bestSuitedPhysicalDeviceLocation]; // Causes segfault

Cette ligne ne fait rien que l'appelant puisse voir. Elle va juste changer la variable locale gPhysicalDevice pour pointer vers le début du tableau local physicalDevices . Quand vous revenez, toutes ces choses disparaissent. Le résultat final est que [hysicalDevice dans la portée de l'appelant n'a pas été initialisé. C'est la cause probable de l'erreur de segmentation.

Quand vous faites ça à la place :

  *gPhysicalDevice = physicalDevices[bestSuitedPhysicalDeviceLocation]; // Works

En fait, vous copiez la valeur du premier élément de l'élément physicalDevices[] dans la variable physicalDevice dans la portée de l'appelant.

Notez que si vous allez toujours chercher le premier dispositif physique, vous n'avez pas besoin de créer un tableau local, vous pouvez simplement le faire :

void populatePhysicalDevice(VkInstance* gInstance, VkPhysicalDevice* gPhysicalDevice)
{
  vkEnumeratePhysicalDevices(*gInstance, 1, gPhysicalDevices);
}

Mais n'oubliez pas que l'instance peut ne pas avoir de dispositifs physiques disponibles. Vérifiez donc les valeurs de retour des fonctions que vous appelez et assurez-vous qu'elles sont conformes aux attentes !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X